===================== The Django admin site ===================== One of the most powerful parts of Django is the automatic admin interface. It reads metadata in your model to provide a powerful and production-ready interface that content producers can immediately use to start adding content to the site. In this document, we discuss how to activate, use and customize Django's admin interface. .. admonition:: Note The admin site has been refactored significantly since Django 0.96. This document describes the newest version of the admin site, which allows for much richer customization. If you follow the development of Django itself, you may have heard this described as "newforms-admin." Overview ======== There are four steps in activating the Django admin site: 1. Determine which of your application's models should be editable in the admin interface. 2. For each of those models, optionally create a ``ModelAdmin`` class that encapsulates the customized admin functionality and options for that particular model. 3. Instantiate an ``AdminSite`` and tell it about each of your models and ``ModelAdmin`` classes. 4. Hook the ``AdminSite`` instance into your URLconf. ``ModelAdmin`` objects ====================== The ``ModelAdmin`` class is the representation of a model in the admin interface. These are stored in a file named ``admin.py`` in your application. Let's take a look at a very simple example the ``ModelAdmin``:: from django.contrib import admin from myproject.myapp.models import Author class AuthorAdmin(admin.ModelAdmin): pass admin.site.register(Author, AuthorAdmin) The ``ModelAdmin`` is very flexible. It has several options for dealing with customizing the interface. All options are defined on the ``ModelAdmin`` subclass:: class AuthorAdmin(admin.ModelAdmin): date_hierarchy = 'pub_date' ``date_hierarchy`` ------------------ Set ``date_hierarchy`` to the name of a ``DateField`` or ``DateTimeField`` in your model, and the change list page will include a date-based drilldown navigation by that field. Example:: date_hierarchy = 'pub_date' ``fieldsets`` ------------- Set ``fieldsets`` to control the layout of admin "add" and "change" pages. ``fieldsets`` is a list of two-tuples, in which each two-tuple represents a ``
`` on the admin form page. (A ``
`` is a "section" of the form.) The two-tuples are in the format ``(name, field_options)``, where ``name`` is a string representing the title of the fieldset and ``field_options`` is a dictionary of information about the fieldset, including a list of fields to be displayed in it. A full example, taken from the ``django.contrib.flatpages.FlatPage`` model:: class FlatPageAdmin(admin.ModelAdmin): fieldsets = ( (None, { 'fields': ('url', 'title', 'content', 'sites') }), ('Advanced options', { 'classes': ('collapse',), 'fields': ('enable_comments', 'registration_required', 'template_name') }), ) This results in an admin page that looks like: .. image:: http://media.djangoproject.com/img/doc/flatfiles_admin.png If ``fieldsets`` isn't given, Django will default to displaying each field that isn't an ``AutoField`` and has ``editable=True``, in a single fieldset, in the same order as the fields are defined in the model. The ``field_options`` dictionary can have the following keys: ``fields`` ~~~~~~~~~~ A tuple of field names to display in this fieldset. This key is required. Example:: { 'fields': ('first_name', 'last_name', 'address', 'city', 'state'), } To display multiple fields on the same line, wrap those fields in their own tuple. In this example, the ``first_name`` and ``last_name`` fields will display on the same line:: { 'fields': (('first_name', 'last_name'), 'address', 'city', 'state'), } ``classes`` ~~~~~~~~~~~ A string containing extra CSS classes to apply to the fieldset. Example:: { 'classes': 'wide', } Apply multiple classes by separating them with spaces. Example:: { 'classes': 'wide extrapretty', } Two useful classes defined by the default admin-site stylesheet are ``collapse`` and ``wide``. Fieldsets with the ``collapse`` style will be initially collapsed in the admin and replaced with a small "click to expand" link. Fieldsets with the ``wide`` style will be given extra horizontal space. ``description`` ~~~~~~~~~~~~~~~ A string of optional extra text to be displayed at the top of each fieldset, under the heading of the fieldset. It's used verbatim, so you can use any HTML and you must escape any special HTML characters (such as ampersands) yourself. ``list_display`` ---------------- Set ``list_display`` to control which fields are displayed on the change list page of the admin. Example:: list_display = ('first_name', 'last_name') If you don't set ``list_display``, the admin site will display a single column that displays the ``__unicode__()`` representation of each object. A few special cases to note about ``list_display``: * If the field is a ``ForeignKey``, Django will display the ``__unicode__()`` of the related object. * ``ManyToManyField`` fields aren't supported, because that would entail executing a separate SQL statement for each row in the table. If you want to do this nonetheless, give your model a custom method, and add that method's name to ``list_display``. (See below for more on custom methods in ``list_display``.) * If the field is a ``BooleanField`` or ``NullBooleanField``, Django will display a pretty "on" or "off" icon instead of ``True`` or ``False``. * If the string given is a method of the model, Django will call it and display the output. This method should have a ``short_description`` function attribute, for use as the header for the field. Here's a full example model:: class Person(models.Model): name = models.CharField(max_length=50) birthday = models.DateField() def decade_born_in(self): return self.birthday.strftime('%Y')[:3] + "0's" decade_born_in.short_description = 'Birth decade' class PersonAdmin(admin.ModelAdmin): list_display = ('name', 'decade_born_in') * If the string given is a method of the model, Django will HTML-escape the output by default. If you'd rather not escape the output of the method, give the method an ``allow_tags`` attribute whose value is ``True``. Here's a full example model:: class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) def colored_name(self): return '%s %s' % (self.color_code, self.first_name, self.last_name) colored_name.allow_tags = True class PersonAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'colored_name') * If the string given is a method of the model that returns True or False Django will display a pretty "on" or "off" icon if you give the method a ``boolean`` attribute whose value is ``True``. Here's a full example model:: class Person(models.Model): first_name = models.CharField(max_length=50) birthday = models.DateField() def born_in_fifties(self): return self.birthday.strftime('%Y')[:3] == 5 born_in_fifties.boolean = True class PersonAdmin(admin.ModelAdmin): list_display = ('name', 'born_in_fifties') * The ``__str__()`` and ``__unicode__()`` methods are just as valid in ``list_display`` as any other model method, so it's perfectly OK to do this:: list_display = ('__unicode__', 'some_other_field') * Usually, elements of ``list_display`` that aren't actual database fields can't be used in sorting (because Django does all the sorting at the database level). However, if an element of ``list_display`` represents a certain database field, you can indicate this fact by setting the ``admin_order_field`` attribute of the item. For example:: class Person(models.Model): first_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) def colored_first_name(self): return '%s' % (self.color_code, self.first_name) colored_first_name.allow_tags = True colored_first_name.admin_order_field = 'first_name' class PersonAdmin(admin.ModelAdmin): list_display = ('first_name', 'colored_first_name') The above will tell Django to order by the ``first_name`` field when trying to sort by ``colored_first_name`` in the admin. ``list_display_links`` ---------------------- Set ``list_display_links`` to control which fields in ``list_display`` should be linked to the "change" page for an object. By default, the change list page will link the first column -- the first field specified in ``list_display`` -- to the change page for each item. But ``list_display_links`` lets you change which columns are linked. Set ``list_display_links`` to a list or tuple of field names (in the same format as ``list_display``) to link. ``list_display_links`` can specify one or many field names. As long as the field names appear in ``list_display``, Django doesn't care how many (or how few) fields are linked. The only requirement is: If you want to use ``list_display_links``, you must define ``list_display``. In this example, the ``first_name`` and ``last_name`` fields will be linked on the change list page:: class PersonAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'birthday') list_display_links = ('first_name', 'last_name') Finally, note that in order to use ``list_display_links``, you must define ``list_display``, too. ``list_filter`` --------------- Set ``list_filter`` to activate filters in the right sidebar of the change list page of the admin. This should be a list of field names, and each specified field should be either a ``BooleanField``, ``CharField``, ``DateField``, ``DateTimeField``, ``IntegerField`` or ``ForeignKey``. This example, taken from the ``django.contrib.auth.models.User`` model, shows how both ``list_display`` and ``list_filter`` work:: class UserAdmin(admin.ModelAdmin): list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff') list_filter = ('is_staff', 'is_superuser') The above code results in an admin change list page that looks like this: .. image:: http://media.djangoproject.com/img/doc/users_changelist.png (This example also has ``search_fields`` defined. See below.) ``list_per_page`` ----------------- Set ``list_per_page`` to control how many items appear on each paginated admin change list page. By default, this is set to ``100``. ``list_select_related`` ----------------------- Set ``list_select_related`` to tell Django to use ``select_related()`` in retrieving the list of objects on the admin change list page. This can save you a bunch of database queries. The value should be either ``True`` or ``False``. Default is ``False``. Note that Django will use ``select_related()``, regardless of this setting, if one of the ``list_display`` fields is a ``ForeignKey``. For more on ``select_related()``, see `the select_related() docs`_. .. _the select_related() docs: ../db-api/#select-related ``inlines`` ----------- See ``InlineModelAdmin`` objects below. ``ordering`` ------------ Set ``ordering`` to specify how objects on the admin change list page should be ordered. This should be a list or tuple in the same format as a model's ``ordering`` parameter. If this isn't provided, the Django admin will use the model's default ordering. ``radio_fields`` ---------------- By default, Django's admin uses a select-box interface (