I have a number of models with a ForeignKey relationship to a Person
model. For example:
class PersonData(BaseModel):
person = models.ForeignKey(Person)
data = models.TextField()
I want to lock down the admin such that once a PersonData
object is created, an admin user can change the data, but can't change the Person
.
At first it seemed pretty straightforward -- I put this in the PersonDataAdmin
class:
def get_readonly_fields(self, request, obj=None):
if obj:
return self.readonly_fields + ('person',)
return self.readonly_fields
On the display side, that worked as expected -- I see the value for person
, but it's grayed out so I can't change it -- but then when I try to change the data and submit the form, I get an error message, "Please correct the error below." No other message appears, but with a bit of digging, I discovered that the form is missing a value for the required person
field.
I've investigated a solution that would involve creating a custom form that would disable this field selectively (something like this or this), but (a) I wasn't successful in getting it to work, and (b) it seemed like a ton of code for what seems like a much simpler situation. I also looked into using exclude
, but ran into the same problem as read_only
.
Any ideas for how to accomplish this? Thank you!
Django admin by default shows all fields as editable and this fields option will display its data as-is and non-editable. we use readonly_fields is used without defining explicit ordering through ModelAdmin or ModelAdmin. fieldsets they will be added. Now we make the Question text fields read-only.
The simplest way is by using the field option blank=True (docs.djangoproject.com/en/dev/ref/models/fields/#blank).
Every field comes in with built-in validations from Django validators. One can also add more built-in field validations for applying or removing certain constraints on a particular field. editable=False will make the field disappear from all forms including admin and ModelForm i.e., it can not be edited using any form.
fieldsets is a list of two-tuples, in which each two-tuple represents a <fieldset> on the admin form page. (A <fieldset> is a “section” of the form.)
field1 is a required field here and it is made as read only in admin screen
class ModelName(models.Model):
field1 = models.ForeignKey(
ModelA,
on_delete=models.CASCADE,
db_column='col1',
related_name='col1',
verbose_name='col1'
)
field2 = models.ForeignKey(
ModelB,
on_delete=models.CASCADE,
db_column='col2',
related_name='col2',
verbose_name='col2'
)
@admin.register(ModelName)
class AdminClassName(admin.ModelAdmin):
fields = ('field1', 'field2')
readonly_fields = ('field1')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With