Django Admin Model Form – Show and Hide fields

It took a while to understand how to customize the Django admin model form to show/hide fields. This can be broken down into two categories: ModelAdmin objects and InlineModelAdmin objects.

ModelAdmin objects – The ModelAdmin class is the representation of a model in the admin interface. Usually, these are stored in a file named in your application.

InlineModelAdmin objects – The admin interface has the ability to edit models on the same page as a parent model. These are called inlines. They can belong to TabularInline class or StackedInline class.

To show an additional field on the admin model form, you can define them within fieldsets in the class the represents your model. e.g. a new field msp_host was added to the form by adding it to the fieldsets:

class EvalInstallationTenantAdmin(admin.ModelAdmin):
    fieldsets = ( ('Tenant Info', {'fields': ('tenant_id', 'name', 'host_name', 'host_controller', 'deployment_type', 'msp_host', 'bandwidth_limit', 'storage_limit', 'deployment_key', 'filex_key', 'license_key', 'software_version', 'update_server', 'license_generated_at'), 'classes': ['wide']}),)

To not show the field, simple remove it from the fieldsets.

Now, a model form may show a parent model and a child model – both on the same page. In my case, I had a class EvalInstallationAdmin(admin.ModelAdmin) that represented the model Installation. The class EvalInstallationTenantAdmin(admin.ModelAdmin) defined above represnted a model InstallationTenant that is a child key of Installation, i.e. Installation is a foreign key in the InstallationTenant model. Therefore, the edit screen for the Installation model showed data for both – Installation and InstallationTenant. This can be achieved by following:

class EvalInstallationAdmin(admin.ModelAdmin):
    fieldsets = ( ('Installation Info', {'fields': ('account', 'name', 'active_since', 'current_license_start', 'support_expires', 'termination_date', 'notes'), 'classes': ['wide']}),
                  ('Deployment Info', {'fields': ( 'status', 'package_type', 'installation_type',), 'classes': ['wide']}),
                  ('Support Extension Info', {'fields': ('support_extension', 'support_extended_by', ), 'classes': ['wide']}),
    readonly_fields = ('account',)
    ordering = ('name',)
    list_display = ('name', 'notes')
    #list_filter = ['customer_name',]#'owner']
    #search_fields = ['customer_name',]#'owner']
    inlines = [EvalInstallationTenantInline, ]
    formfield_overrides = {
        models.CharField: {'widget': TextInput(attrs={'size':'60'})},
        models.TextField: {'widget': Textarea(attrs={'rows':6, 'cols':60})},

Therefore, to hide the msp_host field that belongs to the InstlallationTenant object shown on the Installation admin form – changes had to be made to the EvalInstallationTenantInline class that is of type StackedInline. Within the inline class, I assigned the ‘msp_host’ to the exclude variable that overrides the StackedInline class which is responsible for hiding fields for an inline form.

class EvalInstallationTenantInline(admin.StackedInline):
    model = EvalInstallationTenant
    extra = 0
    verbose_name_plural = 'Tenants'
    readonly_fields = ('attributeinfo', 'overrideinfo', 'editlink', )
    exclude = ['msp_host']


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s