Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django admin: hide read-only fields on new records?

I'm using the Django admin site with some readonly fields on records:

class BookAdmin(admin.ModelAdmin):
    fieldsets = [
    (None, {'fields': ['title', 'library_id', 'is_missing', \
                       'transactions_all_time']}),
    ]
    readonly_fields = ['transactions_all_time',]
    list_display = ('library_id', 'author', 'title')

This works great when editing records - the transactions_all_time field is read-only, just as I want.

However, when adding new records it behaves a bit oddly. I get a read-only section at the bottom of the page, which I can't edit and which is irrelevant at this point.

It would be much better if this field was not present at all when adding new records.

Is there any Django option for not displaying read-only fields while adding a new record? I know I can hack the CSS on add_form.html to hide it, but is there a better way?

Thanks.

like image 323
AP257 Avatar asked Feb 23 '11 13:02

AP257


3 Answers

I had similar problem. Resolved it like this

class MyModelAdmin(admin.ModelAdmin):
    readonly_fields = ('field_one',)
    def get_readonly_fields(self, request, obj=None):
        if obj: # Editing
            return self.readonly_fields
        return ()
like image 101
zaan Avatar answered Nov 11 '22 08:11

zaan


Here's a DRY version of Kushal's solution:

def get_fieldsets(self, request, obj=None):
    def if_editing(*args):
        return args if obj else ()
    return (
        (None, {
            'classes': ('wide',),
            'fields': if_editing('admin_thumb', 'admin_image',) +
                      ('original_image', 'user', 'supplier', 'customer', 'priority',)}
        ),
    )  

Note that this only works on the main form -- on an inline form, you're passed the main obj, not the inline obj.

like image 27
Jack Cushman Avatar answered Nov 11 '22 09:11

Jack Cushman


I had a similar problem with a slightly different solution. I wanted to hide image previews (read only fields) from the 'new' form (the 'add' view) but display them when fetching a new object:

class PhotoAdmin(admin.ModelAdmin):
readonly_fields = ('admin_image', 'admin_thumb', )
search_fields = ('filename', 'user', 'supplier', 'customer')
list_display= ('admin_thumb','filename', 'user', 'supplier', 'customer')
#fields = ('admin_thumb', 'admin_image', 'original_image', 'user', 'supplier', 'customer')


def get_fieldsets(self, request, obj=None):
    fieldset_existing = (
        (None, {
            'classes': ('wide',),
            'fields': ('admin_thumb', 'admin_image',
                'original_image', 'user', 'supplier', 'customer', 'priority',)}
        ),
    )
    fieldset_new = (
        (None, {
            'classes': ('wide',),
            'fields': ('original_image', 'user', 'supplier', 'customer', 'priority',)}
        ),
    )
    if obj: # Editing
        return fieldset_existing
    return fieldset_new

The #fields line shows the original fields. I admit this solution is not very 'DRY' but it's clear and simple.

like image 38
Kushal Avatar answered Nov 11 '22 08:11

Kushal