Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django admin: Making a required field read-only

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!

like image 716
TAH Avatar asked Jan 02 '18 21:01

TAH


People also ask

How do you make a field readonly in Django admin?

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.

How do you make a field non mandatory in Django admin?

The simplest way is by using the field option blank=True (docs.djangoproject.com/en/dev/ref/models/fields/#blank).

How do you make a field non editable in Django?

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.

What is Fieldsets in Django admin?

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.)


1 Answers

field1 is a required field here and it is made as read only in admin screen

model.py

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.py

    @admin.register(ModelName)
    class AdminClassName(admin.ModelAdmin):
        fields = ('field1', 'field2')
        readonly_fields = ('field1')
like image 188
LCM-DEVELOPER Avatar answered Oct 02 '22 03:10

LCM-DEVELOPER