Admin Interface
The Admin Interface in this codebase is a highly customizable, automatic administrative tool for managing site content. It is built around a registry system where models are associated with configuration classes that define how they should be presented and edited.
Core Components
The admin interface is composed of several key classes that handle everything from URL routing to the layout of individual change forms.
Admin Site
The AdminSite class, found in django/contrib/admin/sites.py, is the central registry for the admin application. It manages which models are available in the admin and handles the generation of URLs for the admin views.
By default, the project uses a global instance of AdminSite called site, which is a DefaultAdminSite (a lazy wrapper around the class specified in AdminConfig.default_site).
# django/contrib/admin/sites.py
class AdminSite:
"""
An AdminSite object encapsulates an instance of the Django admin
application, ready to be hooked in to your URLconf.
"""
site_title = gettext_lazy("Django site admin")
site_header = gettext_lazy("Django administration")
index_title = gettext_lazy("Site administration")
def register(self, model_or_iterable, admin_class=None, **options):
# Registers models with their corresponding ModelAdmin class
...
ModelAdmin
The ModelAdmin class in django/contrib/admin/options.py is the primary way to customize the admin interface for a specific model. It encapsulates all the options and functionality for a model's admin representation, including the list view (changelist), add form, and change form.
Key attributes for customization include:
list_display: Controls which fields are displayed on the changelist page.list_filter: Adds a sidebar for filtering the changelist by specific fields.search_fields: Enables a search box that queries the specified fields.fieldsets: Allows grouping fields into sections on the add/change pages.
InlineModelAdmin
For managing related objects on the same page as a parent object, the codebase provides InlineModelAdmin and its two main subclasses: TabularInline and StackedInline. These are also located in django/contrib/admin/options.py.
- TabularInline: Displays related objects in a compact, table-based format.
- StackedInline: Displays related objects in a vertical stack, with each object having its own fieldset.
Model Registration
Models must be registered with an AdminSite to appear in the interface. This is typically done in an admin.py file within an application.
Using the Register Method
The most direct way is calling admin.site.register():
from django.contrib import admin
from .models import MyModel
admin.site.register(MyModel)
Using the Register Decorator
The codebase also provides a @register decorator in django/contrib/admin/decorators.py for a more declarative style:
from django.contrib import admin
from .models import Question
@admin.register(Question)
class QuestionAdmin(admin.ModelAdmin):
list_display = ["question_text", "pub_date"]
Practical Implementation Example
A comprehensive example of how these pieces fit together can be found in the project's documentation (docs/intro/tutorial07.txt), demonstrating a complex ModelAdmin with inlines and fieldsets:
from django.contrib import admin
from .models import Question, Choice
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {"fields": ["question_text"]}),
("Date information", {"fields": ["pub_date"], "classes": ["collapse"]}),
]
inlines = [ChoiceInline]
list_display = ["question_text", "pub_date", "was_published_recently"]
list_filter = ["pub_date"]
search_fields = ["question_text"]
admin.site.register(Question, QuestionAdmin)
Audit Trail and Logging
The admin interface automatically tracks changes made by users through the LogEntry model in django/contrib/admin/models.py. Every addition, change, or deletion is recorded with a timestamp, the user who performed the action, and a description of the change.
# django/contrib/admin/models.py
class LogEntry(models.Model):
action_time = models.DateTimeField(_("action time"), default=timezone.now, editable=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, models.CASCADE, verbose_name=_("user"))
content_type = models.ForeignKey(ContentType, models.SET_NULL, blank=True, null=True)
object_id = models.TextField(_("object id"), blank=True, null=True)
action_flag = models.PositiveSmallIntegerField(_("action flag"), choices=ACTION_FLAG_CHOICES)
change_message = models.TextField(_("change message"), blank=True)
Documentation Generator (admindocs)
The admindocs application (django/contrib/admindocs) provides an automatic documentation system for the project. It uses introspection to generate documentation for:
- Models: Fields, methods, and relationships.
- Views: URL patterns and associated view functions.
- Template Tags and Filters: Available tags and filters with their docstrings.
This is integrated into the admin interface, allowing staff users to browse the technical structure of the site directly from the admin dashboard.
Advanced Customization
Custom AdminSite
If a project requires multiple independent admin interfaces (e.g., one for site editors and one for superusers), multiple AdminSite instances can be created:
class MyCustomAdminSite(admin.AdminSite):
site_header = "Custom Administration"
custom_site = MyCustomAdminSite(name="custom_admin")
custom_site.register(MyModel)
System Checks
The admin application includes a suite of system checks in django/contrib/admin/checks.py that validate the configuration of ModelAdmin classes. These checks ensure that fields referenced in list_display, list_filter, and other attributes actually exist on the model and are configured correctly. For example, ModelAdminChecks verifies that list_editable fields are also present in list_display.