2
votes

I'm developing a Django project in which I want to allow users to edit a specific field only on add_view. So I've overridden the change_view method on the admin.py so it can set my readonly_fields there. However Django won't display readonly_fields.

It seems really wird for me that a readonly field is not displayed. I mean, if it's readonly, where is the part of it where it says read? It should be readable (only), and not ediable. If I wanted to hide it, there should be an option called hidden_fields or something. Don't you guys agree?

I wonder if is there any straighforward way of make readonly_fields visible on my admin, but not ediable.

my admin.py looks like this:

from django.contrib import admin from core.models import Box

class BoxAdmin(admin.ModelAdmin):
    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.readonly_fields = ('colour',)
        return super(BoxAdmin, self).change_view(request, object_id)

    def add_view(self, request, form_url='', extra_context=None):
        self.readonly_fields = []
        return super(BoxAdmin, self).add_view(request, extra_context=c)
2
Is not enough to add readonly_fields = ('colour',) tuple to your BoxAdmin class? From docs - Gocht
Are you sure it's not there? Unless you explicitly set fields or fieldsets, readonly_fields appear at the bottom, after all editable fields. - Paulo Almeida
@Gocht, Well. It looks like I have to set the fields attribute on my model admin in order readonly_fields to work. That's really strange once it says on the docs that Django will use the fields set on the model as the default field set for ModelAdmin.fields' attribute. - Mauricio
Oh!! Indeed, they appear on the bottom. Sorry guys, my bad. I feel really stupid and dumb right now. - Mauricio
AAARGH. Cost me hours of my life. Anyway. Thanks. Is there a way to put the field up again? - nerdoc

2 Answers

2
votes

Instead of setting self.readonly_fields, you should override get_readonly_fields.

def get_readonly_fields(request, obj=None):
    if obj is None:  # add form
        return []
    else:
        return ['colour']
2
votes

I figured out the problem and it happens to be with my lack of attention. Actually Django does display readonly_fields but I couldn't see it because they are displayed on the bottom of the form. When you don't set the ModelForm.fields attribute they go to the bottom, which was pretty much my case.