How to hide some fields in django-admin?

DjangoDjango Admin

Django Problem Overview


class Book(models.Model):
    title = models.CharField(..., null=True)
    type = models.CharField(...)
    author = models.CharField(...)

I have a simple class in models.py. In admin I would like to hide title of the book (in book details form) when type of the saved book is 1. How do this in a simplest way?

Django Solutions


Solution 1 - Django

For Django > 1.8 one can directly set the fields to be excluded in admin:

 class PostCodesAdmin(admin.ModelAdmin):
      exclude = ('pcname',)

Hidden fields are directly defined in Django's ORM by setting the Field attribute: editable = False

e.g.

class PostCodes(models.Model):
  gisid  = models.IntegerField(primary_key=True)
  pcname = models.CharField(max_length=32, db_index=True, editable=False)
  ...

However, setting or changing the model's fields directly may not always be possible or advantegous. In principle the following admin.py setup could work, but won't since exclude is an InlineModelAdmin option.

class PostCodesAdmin(admin.ModelAdmin):
     exclude = ('pcname',)
....

A solution working at least in Django 1.4 (and likely later version numbers) is:

class PostCodesAdmin(admin.ModelAdmin):
  def get_form(self, request, obj=None, **kwargs):
      form = super(PostCodesAdmin, self).get_form(request, obj, **kwargs)
      del form.base_fields['enable_comments'] 
      return form

For the admin list-view of the items, it suffices to simply leave out fields not required: e.g.

class PostCodesAdmin(admin.ModelAdmin):
  list_display = ('id', 'gisid', 'title', )

Solution 2 - Django

You are to create admin.py in your module (probably book)

class BookAdmin(admin.ModelAdmin):
    list_display = ("pk", "get_title_or_nothing")

In Book class:

class Book:
    ...
    def get_title_or_nothing(self):
        if self.type == WEIRD_TYPE:
            return ""
        return self.title

UPDATED:

class BookAdmin(admin.ModelAdmin):
    list_display = ("pk", "get_title_or_nothing")

    def get_form(self, request, obj=None, **kwargs):
        if obj.type == "1":
            self.exclude = ("title", )
        form = super(BookAdmin, self).get_form(request, obj, **kwargs)
        return form

Solution 3 - Django

I tried to override get_form() function but some mix up errors occur when I switch in different records. I found there is a get_exclude() function we can override.

Use:

class BookAdmin(admin.ModelAdmin):
    def get_exclude(self, request, obj=None):
        if obj and obj.type == "1":
            # When you create new data the obj is None
            return ("title", )
        return super().get_exclude(request, obj)

Solution 4 - Django

class BookAdmin(admin.ModelAdmin):
    exclude = ("fieldname",)  # hide fields which you want

Solution 5 - Django

Apropos @Lorenz @mrts answer

with Django 2.1 I found that exclude does not work if the field is already specified via fields = .

In that case you may use

self.fields.remove('title')

fields will have to be defined as a list [] for this to work

Solution 6 - Django

If you want to maintain the value in the form (for example set a value, i.e. user, based on the request) and hide the field, you can change the widget to forms.HiddenInput():

from django import forms

...

    def get_form(self, request, obj=None, **kwargs):
        """Set defaults based on request user"""
        # update user field with logged user as default
        form = super().get_form(request, obj, **kwargs)
        form.base_fields["user"].initial = request.user.id
        form.base_fields["user"].widget = forms.HiddenInput()
        return form

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpmoniqView Question on Stackoverflow
Solution 1 - DjangoLorenz Lo SauerView Answer on Stackoverflow
Solution 2 - DjangoAleksej VasinovView Answer on Stackoverflow
Solution 3 - DjangovividmoonView Answer on Stackoverflow
Solution 4 - Djangouser18972996View Answer on Stackoverflow
Solution 5 - Djangomb_atxView Answer on Stackoverflow
Solution 6 - DjangomonkutView Answer on Stackoverflow