Admin Page Customization In Django

The Django framework comes with a powerful administrative tool called admin. You can use it out of the box to quickly add, delete, or edit any database model from a web interface. But with a little extra code, you can customize the Django admin to take your admin capabilities to the next level

In this tutorial we are going to do

  • Add attribute columns in model object list
  • Add filter to the model object list
  • Make the model object searchable

Setting Up Django Admin

The Django admin provides a web-based interface for creating and managing database model objects. To see it in action, you’ll first need a Django Project and some object models. Install Django inside a clean virtual environment:

$ django-admin startproject custome
$ cd custom
$ python manage.py startapp core
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py createsuperuser

Username: admin
Email address: [email protected]
Password:
Password (again):

You first create a new Django project named custom with an app called core. Then you migrate the authentication tables and create an administrator. Access to the Django admin screens is restricted to users with staff or superuser flags, so you use the createsuperuser management command to create a superuser.

You also need to modify custom/settings.py to include the new app named core:

# custom/settings.py
# ...

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "core",    # Add this line
]

You’re interested in two of these files:

  1. models.py defines your database models.
  2. admin.py registers your models with the Django admin.

To demonstrate the outcome when you customize the Django admin, you’ll need some models. Edit core/models.py:

models.py

from django.db import models

# Create your models here.

class Team(models.Model):
  first_name = models.CharField(max_length=255)
  last_name = models.CharField(max_length=255)
  designation = models.CharField(max_length=255)
  photo = models.ImageField(upload_to='photos/%Y/%m/%d/')
  facebook_link = models.URLField(max_length=255)
  twitter_link = models.URLField(max_length=255)
  google_plus_link = models.URLField(max_length=255)
  created_date = models.DateTimeField(auto_now_add=True)


These models represent personal of Office Members in the Office. A Person has a first and last name, designation, photo etc.

Model that you want Django to represent in the admin interface needs to be registered. You do this in the admin.py file. Models from core/models.py are registered in the corresponding core/admin.py file:

admin.py

from django.contrib import admin
from .models import Team


admin.site.register(Team)

You’re almost ready to go. Once you’ve migrated your database models, you can run the Django development server and see the results:

$ ./manage.py makemigrations
$ ./manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, core, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  ...
  Applying core.0001_initial... OK
  Applying core.0002_auto_20200609_2120... OK
  Applying sessions.0001_initial... OK
$ ./manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
Django version 3.0.7, using settings 'School.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Now visit http://127.0.0.1:8000/admin to see your admin interface. You’ll be prompted to log in. Use the credentials you created with the createsuperuser management command.

The admin home screen lists all the registered database models:

The list starts out empty, like your database. Clicking ADD TEAM allows you to create a person in the database.

The good news is you’ve got an object. The bad news is Team object (1) tells you the id of the object and nothing else. By default, the Django admin displays each object by calling str() on it. You can make this screen a little more helpful by adding a .__str__() method to the Team class in core/models.py to display FIrstName:

Modifying a Change List Using list_display in Admin Page

Implementing .__str__() is a quick way to change the representation of a Person object from a meaningless string to understandable data. Since this representation will also show up in drop-downs and multi-selects, you definitely want to make it as easy to understand as possible.

You can customize change list pages in far more ways than just modifying an object’s string representation. The list_display attribute of an admin.ModelAdmin object specifies what columns are shown in the change list. For example, in core/admin.py, modify TeamAdmin as follows:

from django.contrib import admin
from .models import Team
from django.utils.html import format_html


class TeamAdmin(admin.ModelAdmin):


  list_display = ('id' , 'first_name', 'designation','created_date')






admin.site.register(Team, TeamAdmin)

# Register your models here.

Then The Output of above is

Providing Links to Other Object Pages

You can point list_display at a method that returns an HTML link. Inside core/admin.py, modify the TeamAdmin class and you also display the small part of Person’s photo as thumbnail as follows:

from django.contrib import admin
from .models import Team
from django.utils.html import format_html


class TeamAdmin(admin.ModelAdmin):
  def thumbnail(self,object):
    return format_html('<img src= "{}" width="40" style="border-radius: 50px;" />'.format(object.photo.url))
  
  thumbnail.short_description = 'photo'

  list_display = ('id' ,'thumbnail' , 'first_name', 'designation','created_date')
  list_display_links = ('id' , 'first_name',)






admin.site.register(Team, TeamAdmin)

# Register your models here.

Adding Filters to the List Screen

In addition to filtering data on the change list through the calling URL, you can also filter with a built-in widget. Add the list_filter attribute to the TeamAdmin object in core/admin.py:

from django.contrib import admin
from .models import Team
from django.utils.html import format_html


class TeamAdmin(admin.ModelAdmin):
  def thumbnail(self,object):
    return format_html('<img src= "{}" width="40" style="border-radius: 50px;" />'.format(object.photo.url))
  
  thumbnail.short_description = 'photo'

  list_display = ('id' ,'thumbnail' , 'first_name', 'designation','created_date')
  list_display_links = ('id' , 'first_name',)
  list_filter = ('designation',)






admin.site.register(Team, TeamAdmin)

# Register your models here.

Adding Search to the List Screen

Filters aren’t the only way to reduce the amount of data on the screen. Django admin also supports searching through the search_fields option, which adds a search box to the screen. set it with a tuple containing the names of fields to be used for constructing a search query in the database.

Anything the user types in the search box is used in an OR clause of the fields filtering the QuerySet. By default, each search parameter is surrounded by % signs, meaning if you search for r, then any word with an r inside will appear in the results. You can be more precise by specifying a __ modifier on the search field.

Edit the TeamAdmin in core/admin.py as follows:

Conclusion

The Django admin is a powerful built-in tool giving you the ability to create, update, and delete objects in your database using a web interface. You can customize the Django admin to do almost anything you want.