CodeMIRAI
0 XP

The admin site

2 min read Quiz included

Django comes with a complete admin site: a password-protected interface where staff can add, change and delete data in any model, with almost no code. For many projects, it replaces a whole internal tool.

Logging in

The admin is switched on in every new project: django.contrib.admin is in INSTALLED_APPS, and config/urls.py contains path("admin/", admin.site.urls). Create an account that may use it:

Terminal
python manage.py createsuperuser
Output
Username: asha
Email address: asha@example.com
Password:
Password (again):
Superuser created successfully.

Run python manage.py runserver and open http://127.0.0.1:8000/admin/. After logging in, you'll see the Users and Groups models from django.contrib.auth, but not yet your own.

Registering a model

In the app's admin.py:

Python
from django.contrib import admin

from .models import Course

admin.site.register(Course)

Refresh the admin, and Courses appears, with pages to list, add, edit and delete courses. The forms are built from the model's fields, with validation, drop-downs for choices and date pickers for dates. The list shows each object using its __str__ method, which is why every model should have one.

Customising the list page

Python
from django.contrib import admin

from .models import Course


@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
    list_display = ["title", "category", "price", "published"]   # columns on the list page
    list_filter = ["category", "published"]                      # a filter sidebar
    search_fields = ["title", "description"]                     # a search box
    list_editable = ["price", "published"]                       # edit right in the list
    ordering = ["title"]
    prepopulated_fields = {"slug": ("title",)}                   # fill the slug as you type the title
OptionAdds
list_displaycolumns on the list page, which can include model methods
list_filtera sidebar for narrowing the list down by field
search_fieldsa search box over those fields
list_editablefields that can be edited directly in the list
date_hierarchynavigation by year, month and day for a date field
readonly_fieldsfields shown but not editable

@admin.register(Course) does the same as admin.site.register(Course, CourseAdmin), written as a decorator.

Python
class LessonInline(admin.TabularInline):
    model = Lesson
    extra = 1          # one empty row for adding a new lesson


@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
    list_display = ["title", "lesson_count"]
    inlines = [LessonInline]

    @admin.display(description="Lessons")
    def lesson_count(self, obj):
        return obj.lessons.count()

An inline shows a course's lessons as a table on the course's edit page, so both can be edited at once. A method like lesson_count can appear in list_display as a calculated column.

Bulk actions

Python
@admin.action(description="Publish the selected courses")
def publish(modeladmin, request, queryset):
    updated = queryset.update(published=True)
    modeladmin.message_user(request, f"{updated} courses published.")


@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
    actions = [publish]

Tick some rows on the list page, pick Publish the selected courses from the Action menu, and the function runs on the selected objects.

Finished this lesson?Mark it complete to earn +20 XP and move your progress on.