App Engine Python SDK version 1.9.12
[gae.git] / python / lib / django-1.2 / docs / ref / contrib / admin / index.txt
blobcfc15ed8f55af829209440b30ad52316ee2a29a1
1 =====================
2 The Django admin site
3 =====================
5 .. module:: django.contrib.admin
6    :synopsis: Django's admin site.
8 One of the most powerful parts of Django is the automatic admin interface. It
9 reads metadata in your model to provide a powerful and production-ready
10 interface that content producers can immediately use to start adding content to
11 the site. In this document, we discuss how to activate, use and customize
12 Django's admin interface.
14 .. admonition:: Note
16     The admin site has been refactored significantly since Django 0.96. This
17     document describes the newest version of the admin site, which allows for
18     much richer customization. If you follow the development of Django itself,
19     you may have heard this described as "newforms-admin."
21 Overview
22 ========
24 There are six steps in activating the Django admin site:
26     1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS`
27        setting.
29     2. Admin has two dependencies - ``django.contrib.auth`` and
30        ``django.contrib.contenttypes``. If these applications are not
31        in your :setting:`INSTALLED_APPS` list, add them.
33     3. Determine which of your application's models should be editable in the
34        admin interface.
36     4. For each of those models, optionally create a ``ModelAdmin`` class that
37        encapsulates the customized admin functionality and options for that
38        particular model.
40     5. Instantiate an ``AdminSite`` and tell it about each of your models and
41        ``ModelAdmin`` classes.
43     6. Hook the ``AdminSite`` instance into your URLconf.
45 Other topics
46 ------------
48 .. toctree::
49    :maxdepth: 1
51    actions
52    admindocs
54 .. seealso::
56     For information about serving the media files (images, JavaScript, and CSS)
57     associated with the admin in production, see :ref:`serving-media-files`.
59 ``ModelAdmin`` objects
60 ======================
62 .. class:: ModelAdmin
64 The ``ModelAdmin`` class is the representation of a model in the admin
65 interface. These are stored in a file named ``admin.py`` in your application.
66 Let's take a look at a very simple example of the ``ModelAdmin``::
68     from django.contrib import admin
69     from myproject.myapp.models import Author
71     class AuthorAdmin(admin.ModelAdmin):
72         pass
73     admin.site.register(Author, AuthorAdmin)
75 .. admonition:: Do you need a ``ModelAdmin`` object at all?
77     In the preceding example, the ``ModelAdmin`` class doesn't define any
78     custom values (yet). As a result, the default admin interface will be
79     provided. If you are happy with the default admin interface, you don't
80     need to define a ``ModelAdmin`` object at all -- you can register the
81     model class without providing a ``ModelAdmin`` description. The
82     preceding example could be simplified to::
84         from django.contrib import admin
85         from myproject.myapp.models import Author
87         admin.site.register(Author)
89 ``ModelAdmin`` Options
90 ----------------------
92 The ``ModelAdmin`` is very flexible. It has several options for dealing with
93 customizing the interface. All options are defined on the ``ModelAdmin``
94 subclass::
96     class AuthorAdmin(admin.ModelAdmin):
97         date_hierarchy = 'pub_date'
99 .. attribute:: ModelAdmin.date_hierarchy
101 Set ``date_hierarchy`` to the name of a ``DateField`` or ``DateTimeField`` in
102 your model, and the change list page will include a date-based drilldown
103 navigation by that field.
105 Example::
107     date_hierarchy = 'pub_date'
109 .. attribute:: ModelAdmin.form
111 By default a ``ModelForm`` is dynamically created for your model. It is used
112 to create the form presented on both the add/change pages. You can easily
113 provide your own ``ModelForm`` to override any default form behavior on the
114 add/change pages.
116 For an example see the section `Adding custom validation to the admin`_.
118 .. attribute:: ModelAdmin.fieldsets
120 Set ``fieldsets`` to control the layout of admin "add" and "change" pages.
122 ``fieldsets`` is a list of two-tuples, in which each two-tuple represents a
123 ``<fieldset>`` on the admin form page. (A ``<fieldset>`` is a "section" of the
124 form.)
126 The two-tuples are in the format ``(name, field_options)``, where ``name`` is a
127 string representing the title of the fieldset and ``field_options`` is a
128 dictionary of information about the fieldset, including a list of fields to be
129 displayed in it.
131 A full example, taken from the ``django.contrib.flatpages.FlatPage`` model::
133     class FlatPageAdmin(admin.ModelAdmin):
134         fieldsets = (
135             (None, {
136                 'fields': ('url', 'title', 'content', 'sites')
137             }),
138             ('Advanced options', {
139                 'classes': ('collapse',),
140                 'fields': ('enable_comments', 'registration_required', 'template_name')
141             }),
142         )
144 This results in an admin page that looks like:
146     .. image:: _images/flatfiles_admin.png
148 If ``fieldsets`` isn't given, Django will default to displaying each field
149 that isn't an ``AutoField`` and has ``editable=True``, in a single fieldset,
150 in the same order as the fields are defined in the model.
152 The ``field_options`` dictionary can have the following keys:
154     * ``fields``
155         A tuple of field names to display in this fieldset. This key is
156         required.
158         Example::
160             {
161             'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
162             }
164         To display multiple fields on the same line, wrap those fields in
165         their own tuple. In this example, the ``first_name`` and ``last_name``
166         fields will display on the same line::
168             {
169             'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
170             }
172         .. versionadded:: 1.2
174         ``fields`` can contain values defined in
175         :attr:`ModelAdmin.readonly_fields` to be displayed as read-only.
177     * ``classes``
178         A list containing extra CSS classes to apply to the fieldset.
180         Example::
182             {
183             'classes': ['wide', 'extrapretty'],
184             }
186         Two useful classes defined by the default admin site stylesheet are
187         ``collapse`` and ``wide``. Fieldsets with the ``collapse`` style will
188         be initially collapsed in the admin and replaced with a small
189         "click to expand" link. Fieldsets with the ``wide`` style will be
190         given extra horizontal space.
192     * ``description``
193         A string of optional extra text to be displayed at the top of each
194         fieldset, under the heading of the fieldset.
196         Note that this value is *not* HTML-escaped when it's displayed in
197         the admin interface. This lets you include HTML if you so desire.
198         Alternatively you can use plain text and
199         ``django.utils.html.escape()`` to escape any HTML special
200         characters.
202 .. attribute:: ModelAdmin.fields
204 Use this option as an alternative to ``fieldsets`` if the layout does not
205 matter and if you want to only show a subset of the available fields in the
206 form. For example, you could define a simpler version of the admin form for
207 the ``django.contrib.flatpages.FlatPage`` model as follows::
209     class FlatPageAdmin(admin.ModelAdmin):
210         fields = ('url', 'title', 'content')
212 In the above example, only the fields 'url', 'title' and 'content' will be
213 displayed, sequentially, in the form.
215 .. versionadded:: 1.2
217 ``fields`` can contain values defined in :attr:`ModelAdmin.readonly_fields`
218 to be displayed as read-only.
220 .. admonition:: Note
222     This ``fields`` option should not be confused with the ``fields``
223     dictionary key that is within the ``fieldsets`` option, as described in
224     the previous section.
226 .. attribute:: ModelAdmin.exclude
228 This attribute, if given, should be a list of field names to exclude from the
229 form.
231 For example, let's consider the following model::
233     class Author(models.Model):
234         name = models.CharField(max_length=100)
235         title = models.CharField(max_length=3)
236         birth_date = models.DateField(blank=True, null=True)
238 If you want a form for the ``Author`` model that includes only the ``name``
239 and ``title`` fields, you would specify ``fields`` or ``exclude`` like this::
241     class AuthorAdmin(admin.ModelAdmin):
242         fields = ('name', 'title')
244     class AuthorAdmin(admin.ModelAdmin):
245         exclude = ('birth_date',)
247 Since the Author model only has three fields, ``name``, ``title``, and
248 ``birth_date``, the forms resulting from the above declarations will contain
249 exactly the same fields.
251 .. attribute:: ModelAdmin.filter_horizontal
253 Use a nifty unobtrusive JavaScript "filter" interface instead of the
254 usability-challenged ``<select multiple>`` in the admin form. The value is a
255 list of fields that should be displayed as a horizontal filter interface. See
256 ``filter_vertical`` to use a vertical interface.
258 .. attribute:: ModelAdmin.filter_vertical
260 Same as ``filter_horizontal``, but is a vertical display of the filter
261 interface.
263 .. attribute:: ModelAdmin.list_display
265 Set ``list_display`` to control which fields are displayed on the change list
266 page of the admin.
268 Example::
270     list_display = ('first_name', 'last_name')
272 If you don't set ``list_display``, the admin site will display a single column
273 that displays the ``__unicode__()`` representation of each object.
275 You have four possible values that can be used in ``list_display``:
277     * A field of the model. For example::
279           class PersonAdmin(admin.ModelAdmin):
280               list_display = ('first_name', 'last_name')
282     * A callable that accepts one parameter for the model instance. For
283       example::
285           def upper_case_name(obj):
286               return ("%s %s" % (obj.first_name, obj.last_name)).upper()
287           upper_case_name.short_description = 'Name'
289           class PersonAdmin(admin.ModelAdmin):
290               list_display = (upper_case_name,)
292     * A string representing an attribute on the ``ModelAdmin``. This behaves
293       same as the callable. For example::
295           class PersonAdmin(admin.ModelAdmin):
296               list_display = ('upper_case_name',)
298               def upper_case_name(self, obj):
299                 return ("%s %s" % (obj.first_name, obj.last_name)).upper()
300               upper_case_name.short_description = 'Name'
302     * A string representing an attribute on the model. This behaves almost
303       the same as the callable, but ``self`` in this context is the model
304       instance. Here's a full model example::
306           class Person(models.Model):
307               name = models.CharField(max_length=50)
308               birthday = models.DateField()
310               def decade_born_in(self):
311                   return self.birthday.strftime('%Y')[:3] + "0's"
312               decade_born_in.short_description = 'Birth decade'
314           class PersonAdmin(admin.ModelAdmin):
315               list_display = ('name', 'decade_born_in')
317 A few special cases to note about ``list_display``:
319     * If the field is a ``ForeignKey``, Django will display the
320       ``__unicode__()`` of the related object.
322     * ``ManyToManyField`` fields aren't supported, because that would entail
323       executing a separate SQL statement for each row in the table. If you
324       want to do this nonetheless, give your model a custom method, and add
325       that method's name to ``list_display``. (See below for more on custom
326       methods in ``list_display``.)
328     * If the field is a ``BooleanField`` or ``NullBooleanField``, Django will
329       display a pretty "on" or "off" icon instead of ``True`` or ``False``.
331     * If the string given is a method of the model, ``ModelAdmin`` or a
332       callable, Django will HTML-escape the output by default. If you'd rather
333       not escape the output of the method, give the method an ``allow_tags``
334       attribute whose value is ``True``.
336       Here's a full example model::
338           class Person(models.Model):
339               first_name = models.CharField(max_length=50)
340               last_name = models.CharField(max_length=50)
341               color_code = models.CharField(max_length=6)
343               def colored_name(self):
344                   return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name)
345               colored_name.allow_tags = True
347           class PersonAdmin(admin.ModelAdmin):
348               list_display = ('first_name', 'last_name', 'colored_name')
350     * If the string given is a method of the model, ``ModelAdmin`` or a
351       callable that returns True or False Django will display a pretty "on" or
352       "off" icon if you give the method a ``boolean`` attribute whose value is
353       ``True``.
355       Here's a full example model::
357           class Person(models.Model):
358               first_name = models.CharField(max_length=50)
359               birthday = models.DateField()
361               def born_in_fifties(self):
362                   return self.birthday.strftime('%Y')[:3] == '195'
363               born_in_fifties.boolean = True
365           class PersonAdmin(admin.ModelAdmin):
366               list_display = ('name', 'born_in_fifties')
369     * The ``__str__()`` and ``__unicode__()`` methods are just as valid in
370       ``list_display`` as any other model method, so it's perfectly OK to do
371       this::
373           list_display = ('__unicode__', 'some_other_field')
375     * Usually, elements of ``list_display`` that aren't actual database fields
376       can't be used in sorting (because Django does all the sorting at the
377       database level).
379       However, if an element of ``list_display`` represents a certain database
380       field, you can indicate this fact by setting the ``admin_order_field``
381       attribute of the item.
383       For example::
385         class Person(models.Model):
386             first_name = models.CharField(max_length=50)
387             color_code = models.CharField(max_length=6)
389             def colored_first_name(self):
390                 return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name)
391             colored_first_name.allow_tags = True
392             colored_first_name.admin_order_field = 'first_name'
394         class PersonAdmin(admin.ModelAdmin):
395             list_display = ('first_name', 'colored_first_name')
397       The above will tell Django to order by the ``first_name`` field when
398       trying to sort by ``colored_first_name`` in the admin.
400 .. attribute:: ModelAdmin.list_display_links
402 Set ``list_display_links`` to control which fields in ``list_display`` should
403 be linked to the "change" page for an object.
405 By default, the change list page will link the first column -- the first field
406 specified in ``list_display`` -- to the change page for each item. But
407 ``list_display_links`` lets you change which columns are linked. Set
408 ``list_display_links`` to a list or tuple of field names (in the same format as
409 ``list_display``) to link.
411 ``list_display_links`` can specify one or many field names. As long as the
412 field names appear in ``list_display``, Django doesn't care how many (or how
413 few) fields are linked. The only requirement is: If you want to use
414 ``list_display_links``, you must define ``list_display``.
416 In this example, the ``first_name`` and ``last_name`` fields will be linked on
417 the change list page::
419     class PersonAdmin(admin.ModelAdmin):
420         list_display = ('first_name', 'last_name', 'birthday')
421         list_display_links = ('first_name', 'last_name')
423 .. _admin-list-editable:
425 .. attribute:: ModelAdmin.list_editable
427 .. versionadded:: 1.1
429 Set ``list_editable`` to a list of field names on the model which will allow
430 editing on the change list page. That is, fields listed in ``list_editable``
431 will be displayed as form widgets on the change list page, allowing users to
432 edit and save multiple rows at once.
434 .. note::
436     ``list_editable`` interacts with a couple of other options in particular
437     ways; you should note the following rules:
439         * Any field in ``list_editable`` must also be in ``list_display``. You
440           can't edit a field that's not displayed!
442         * The same field can't be listed in both ``list_editable`` and
443           ``list_display_links`` -- a field can't be both a form and a link.
445     You'll get a validation error if either of these rules are broken.
447 .. attribute:: ModelAdmin.list_filter
449 Set ``list_filter`` to activate filters in the right sidebar of the change list
450 page of the admin. This should be a list of field names, and each specified
451 field should be either a ``BooleanField``, ``CharField``, ``DateField``,
452 ``DateTimeField``, ``IntegerField`` or ``ForeignKey``.
454 This example, taken from the ``django.contrib.auth.models.User`` model, shows
455 how both ``list_display`` and ``list_filter`` work::
457     class UserAdmin(admin.ModelAdmin):
458         list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
459         list_filter = ('is_staff', 'is_superuser')
461 The above code results in an admin change list page that looks like this:
463     .. image:: _images/users_changelist.png
465 (This example also has ``search_fields`` defined. See below.)
467 .. attribute:: ModelAdmin.list_per_page
469 Set ``list_per_page`` to control how many items appear on each paginated admin
470 change list page. By default, this is set to ``100``.
472 .. attribute:: ModelAdmin.list_select_related
474 Set ``list_select_related`` to tell Django to use
475 :meth:`~django.db.models.QuerySet.select_related` in retrieving the list of
476 objects on the admin change list page. This can save you a bunch of database
477 queries.
479 The value should be either ``True`` or ``False``. Default is ``False``.
481 Note that Django will use :meth:`~django.db.models.QuerySet.select_related`,
482 regardless of this setting, if one of the ``list_display`` fields is a
483 ``ForeignKey``.
485 .. attribute:: ModelAdmin.inlines
487 See ``InlineModelAdmin`` objects below.
489 .. attribute:: ModelAdmin.ordering
491 Set ``ordering`` to specify how objects on the admin change list page should be
492 ordered. This should be a list or tuple in the same format as a model's
493 ``ordering`` parameter.
495 If this isn't provided, the Django admin will use the model's default ordering.
497 .. admonition:: Note
499     Django will only honor the first element in the list/tuple; any others
500     will be ignored.
502 .. attribute:: ModelAdmin.prepopulated_fields
504 Set ``prepopulated_fields`` to a dictionary mapping field names to the fields
505 it should prepopulate from::
507     class ArticleAdmin(admin.ModelAdmin):
508         prepopulated_fields = {"slug": ("title",)}
510 When set, the given fields will use a bit of JavaScript to populate from the
511 fields assigned. The main use for this functionality is to automatically
512 generate the value for ``SlugField`` fields from one or more other fields. The
513 generated value is produced by concatenating the values of the source fields,
514 and then by transforming that result into a valid slug (e.g. substituting
515 dashes for spaces).
517 ``prepopulated_fields`` doesn't accept ``DateTimeField``, ``ForeignKey``, nor
518 ``ManyToManyField`` fields.
520 .. attribute:: ModelAdmin.radio_fields
522 By default, Django's admin uses a select-box interface (<select>) for
523 fields that are ``ForeignKey`` or have ``choices`` set. If a field is present
524 in ``radio_fields``, Django will use a radio-button interface instead.
525 Assuming ``group`` is a ``ForeignKey`` on the ``Person`` model::
527     class PersonAdmin(admin.ModelAdmin):
528         radio_fields = {"group": admin.VERTICAL}
530 You have the choice of using ``HORIZONTAL`` or ``VERTICAL`` from the
531 ``django.contrib.admin`` module.
533 Don't include a field in ``radio_fields`` unless it's a ``ForeignKey`` or has
534 ``choices`` set.
536 .. attribute:: ModelAdmin.raw_id_fields
538 By default, Django's admin uses a select-box interface (<select>) for
539 fields that are ``ForeignKey``. Sometimes you don't want to incur the
540 overhead of having to select all the related instances to display in the
541 drop-down.
543 ``raw_id_fields`` is a list of fields you would like to change
544 into a ``Input`` widget for either a ``ForeignKey`` or ``ManyToManyField``::
546     class ArticleAdmin(admin.ModelAdmin):
547         raw_id_fields = ("newspaper",)
549 .. attribute:: ModelAdmin.readonly_fields
551 .. versionadded:: 1.2
553 By default the admin shows all fields as editable. Any fields in this option
554 (which should be a ``list`` or ``tuple``) will display its data as-is and
555 non-editable. This option behaves nearly identical to :attr:`ModelAdmin.list_display`.
556 Usage is the same, however, when you specify :attr:`ModelAdmin.fields` or
557 :attr:`ModelAdmin.fieldsets` the read-only fields must be present to be shown
558 (they are ignored otherwise).
560 If ``readonly_fields`` is used without defining explicit ordering through
561 :attr:`ModelAdmin.fields` or :attr:`ModelAdmin.fieldsets` they will be added
562 last after all editable fields.
564 .. attribute:: ModelAdmin.save_as
566 Set ``save_as`` to enable a "save as" feature on admin change forms.
568 Normally, objects have three save options: "Save", "Save and continue editing"
569 and "Save and add another". If ``save_as`` is ``True``, "Save and add another"
570 will be replaced by a "Save as" button.
572 "Save as" means the object will be saved as a new object (with a new ID),
573 rather than the old object.
575 By default, ``save_as`` is set to ``False``.
577 .. attribute:: ModelAdmin.save_on_top
579 Set ``save_on_top`` to add save buttons across the top of your admin change
580 forms.
582 Normally, the save buttons appear only at the bottom of the forms. If you set
583 ``save_on_top``, the buttons will appear both on the top and the bottom.
585 By default, ``save_on_top`` is set to ``False``.
587 .. attribute:: ModelAdmin.search_fields
589 Set ``search_fields`` to enable a search box on the admin change list page.
590 This should be set to a list of field names that will be searched whenever
591 somebody submits a search query in that text box.
593 These fields should be some kind of text field, such as ``CharField`` or
594 ``TextField``. You can also perform a related lookup on a ``ForeignKey`` or
595 ``ManyToManyField`` with the lookup API "follow" notation::
597     search_fields = ['foreign_key__related_fieldname']
599 For example, if you have a blog entry with an author, the following definition
600 would enable search blog entries by the email address of the author::
602     search_fields = ['user__email']
604 When somebody does a search in the admin search box, Django splits the search
605 query into words and returns all objects that contain each of the words, case
606 insensitive, where each word must be in at least one of ``search_fields``. For
607 example, if ``search_fields`` is set to ``['first_name', 'last_name']`` and a
608 user searches for ``john lennon``, Django will do the equivalent of this SQL
609 ``WHERE`` clause::
611     WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
612     AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
614 For faster and/or more restrictive searches, prefix the field name
615 with an operator:
617 ``^``
618     Matches the beginning of the field. For example, if ``search_fields`` is
619     set to ``['^first_name', '^last_name']`` and a user searches for
620     ``john lennon``, Django will do the equivalent of this SQL ``WHERE``
621     clause::
623         WHERE (first_name ILIKE 'john%' OR last_name ILIKE 'john%')
624         AND (first_name ILIKE 'lennon%' OR last_name ILIKE 'lennon%')
626     This query is more efficient than the normal ``'%john%'`` query, because
627     the database only needs to check the beginning of a column's data, rather
628     than seeking through the entire column's data. Plus, if the column has an
629     index on it, some databases may be able to use the index for this query,
630     even though it's a ``LIKE`` query.
632 ``=``
633     Matches exactly, case-insensitive. For example, if
634     ``search_fields`` is set to ``['=first_name', '=last_name']`` and
635     a user searches for ``john lennon``, Django will do the equivalent
636     of this SQL ``WHERE`` clause::
638         WHERE (first_name ILIKE 'john' OR last_name ILIKE 'john')
639         AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')
641     Note that the query input is split by spaces, so, following this example,
642     it's currently not possible to search for all records in which
643     ``first_name`` is exactly ``'john winston'`` (containing a space).
645 ``@``
646     Performs a full-text match. This is like the default search method but uses
647     an index. Currently this is only available for MySQL.
649 .. attribute:: ModelAdmin.formfield_overrides
651 .. versionadded:: 1.1
653 This provides a quick-and-dirty way to override some of the
654 :class:`~django.forms.Field` options for use in the admin.
655 ``formfield_overrides`` is a dictionary mapping a field class to a dict of
656 arguments to pass to the field at construction time.
658 Since that's a bit abstract, let's look at a concrete example. The most common
659 use of ``formfield_overrides`` is to add a custom widget for a certain type of
660 field. So, imagine we've written a ``RichTextEditorWidget`` that we'd like to
661 use for large text fields instead of the default ``<textarea>``. Here's how we'd
662 do that::
664     from django.db import models
665     from django.contrib import admin
667     # Import our custom widget and our model from where they're defined
668     from myapp.widgets import RichTextEditorWidget
669     from myapp.models import MyModel
671     class MyModelAdmin(admin.ModelAdmin):
672         formfield_overrides = {
673             models.TextField: {'widget': RichTextEditorWidget},
674         }
676 Note that the key in the dictionary is the actual field class, *not* a string.
677 The value is another dictionary; these arguments will be passed to
678 :meth:`~django.forms.Field.__init__`. See :doc:`/ref/forms/api` for details.
680 .. warning::
682     If you want to use a custom widget with a relation field (i.e.
683     :class:`~django.db.models.ForeignKey` or
684     :class:`~django.db.models.ManyToManyField`), make sure you haven't included
685     that field's name in ``raw_id_fields`` or ``radio_fields``.
687     ``formfield_overrides`` won't let you change the widget on relation fields
688     that have ``raw_id_fields`` or ``radio_fields`` set. That's because
689     ``raw_id_fields`` and ``radio_fields`` imply custom widgets of their own.
691 .. attribute:: ModelAdmin.actions
693 .. versionadded:: 1.1
695 A list of actions to make available on the change list page. See
696 :doc:`/ref/contrib/admin/actions` for details.
698 .. attribute:: ModelAdmin.actions_on_top
699 .. attribute:: ModelAdmin.actions_on_bottom
701 .. versionadded:: 1.1
703 Controls where on the page the actions bar appears. By default, the admin
704 changelist displays actions at the top of the page (``actions_on_top = True;
705 actions_on_bottom = False``).
707 .. attribute:: ModelAdmin.actions_selection_counter
709 .. versionadded:: 1.2
711 Controls whether a selection counter is display next to the action dropdown.
712 By default, the admin changelist will display it
713 (``actions_selection_counter = True``).
715 Custom template options
716 ~~~~~~~~~~~~~~~~~~~~~~~
718 The `Overriding Admin Templates`_ section describes how to override or extend
719 the default admin templates.  Use the following options to override the default
720 templates used by the :class:`ModelAdmin` views:
722 .. attribute:: ModelAdmin.add_form_template
724     .. versionadded:: 1.2
726     Path to a custom template, used by :meth:`add_view`.
728 .. attribute:: ModelAdmin.change_form_template
730     Path to a custom template, used by :meth:`change_view`.
732 .. attribute:: ModelAdmin.change_list_template
734     Path to a custom template, used by :meth:`changelist_view`.
736 .. attribute:: ModelAdmin.delete_confirmation_template
738     Path to a custom template, used by :meth:`delete_view` for displaying a
739     confirmation page when deleting one or more objects.
741 .. attribute:: ModelAdmin.delete_selected_confirmation_template
743     .. versionadded:: 1.2
745     Path to a custom template, used by the :meth:`delete_selected`
746     action method for displaying a confirmation page when deleting one
747     or more objects. See the :doc:`actions
748     documentation</ref/contrib/admin/actions>`.
750 .. attribute:: ModelAdmin.object_history_template
752     Path to a custom template, used by :meth:`history_view`.
755 .. _model-admin-methods:
757 ``ModelAdmin`` methods
758 ----------------------
760 .. method:: ModelAdmin.save_model(self, request, obj, form, change)
762 The ``save_model`` method is given the ``HttpRequest``, a model instance,
763 a ``ModelForm`` instance and a boolean value based on whether it is adding or
764 changing the object. Here you can do any pre- or post-save operations.
766 For example to attach ``request.user`` to the object prior to saving::
768     class ArticleAdmin(admin.ModelAdmin):
769         def save_model(self, request, obj, form, change):
770             obj.user = request.user
771             obj.save()
773 .. method:: ModelAdmin.save_formset(self, request, form, formset, change)
775 The ``save_formset`` method is given the ``HttpRequest``, the parent
776 ``ModelForm`` instance and a boolean value based on whether it is adding or
777 changing the parent object.
779 For example to attach ``request.user`` to each changed formset
780 model instance::
782     class ArticleAdmin(admin.ModelAdmin):
783         def save_formset(self, request, form, formset, change):
784             instances = formset.save(commit=False)
785             for instance in instances:
786                 instance.user = request.user
787                 instance.save()
788             formset.save_m2m()
790 .. method:: ModelAdmin.get_readonly_fields(self, request, obj=None)
792 .. versionadded:: 1.2
794 The ``get_readonly_fields`` method is given the ``HttpRequest`` and the
795 ``obj`` being edited (or ``None`` on an add form) and is expected to return a
796 ``list`` or ``tuple`` of field names that will be displayed as read-only, as
797 described above in the :attr:`ModelAdmin.readonly_fields` section.
799 .. method:: ModelAdmin.get_urls(self)
801 .. versionadded:: 1.1
803 The ``get_urls`` method on a ``ModelAdmin`` returns the URLs to be used for
804 that ModelAdmin in the same way as a URLconf.  Therefore you can extend them as
805 documented in :doc:`/topics/http/urls`::
807     class MyModelAdmin(admin.ModelAdmin):
808         def get_urls(self):
809             urls = super(MyModelAdmin, self).get_urls()
810             my_urls = patterns('',
811                 (r'^my_view/$', self.my_view)
812             )
813             return my_urls + urls
815 .. note::
817     Notice that the custom patterns are included *before* the regular admin
818     URLs: the admin URL patterns are very permissive and will match nearly
819     anything, so you'll usually want to prepend your custom URLs to the built-in
820     ones.
822 However, the ``self.my_view`` function registered above suffers from two
823 problems:
825   * It will *not* perform any permission checks, so it will be accessible to
826     the general public.
827   * It will *not* provide any header details to prevent caching. This means if
828     the page retrieves data from the database, and caching middleware is
829     active, the page could show outdated information.
831 Since this is usually not what you want, Django provides a convenience wrapper
832 to check permissions and mark the view as non-cacheable. This wrapper is
833 :meth:`AdminSite.admin_view` (i.e. ``self.admin_site.admin_view`` inside a
834 ``ModelAdmin`` instance); use it like so::
836     class MyModelAdmin(admin.ModelAdmin):
837         def get_urls(self):
838             urls = super(MyModelAdmin, self).get_urls()
839             my_urls = patterns('',
840                 (r'^my_view/$', self.admin_site.admin_view(self.my_view))
841             )
842             return my_urls + urls
844 Notice the wrapped view in the fifth line above::
846     (r'^my_view/$', self.admin_site.admin_view(self.my_view))
848 This wrapping will protect ``self.my_view`` from unauthorized access and will
849 apply the ``django.views.decorators.cache.never_cache`` decorator to make sure
850 it is not cached if the cache middleware is active.
852 If the page is cacheable, but you still want the permission check to be performed,
853 you can pass a ``cacheable=True`` argument to :meth:`AdminSite.admin_view`::
855     (r'^my_view/$', self.admin_site.admin_view(self.my_view, cacheable=True))
857 .. method:: ModelAdmin.formfield_for_foreignkey(self, db_field, request, **kwargs)
859 .. versionadded:: 1.1
861 The ``formfield_for_foreignkey`` method on a ``ModelAdmin`` allows you to
862 override the default formfield for a foreign key field. For example, to
863 return a subset of objects for this foreign key field based on the user::
865     class MyModelAdmin(admin.ModelAdmin):
866         def formfield_for_foreignkey(self, db_field, request, **kwargs):
867             if db_field.name == "car":
868                 kwargs["queryset"] = Car.objects.filter(owner=request.user)
869             return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
871 This uses the ``HttpRequest`` instance to filter the ``Car`` foreign key field
872 to only display the cars owned by the ``User`` instance.
874 .. method:: ModelAdmin.formfield_for_manytomany(self, db_field, request, **kwargs)
876 .. versionadded:: 1.1
878 Like the ``formfield_for_foreignkey`` method, the ``formfield_for_manytomany``
879 method can be overridden to change the default formfield for a many to many
880 field. For example, if an owner can own multiple cars and cars can belong
881 to multiple owners -- a many to many relationship -- you could filter the
882 ``Car`` foreign key field to only display the cars owned by the ``User``::
884     class MyModelAdmin(admin.ModelAdmin):
885         def formfield_for_manytomany(self, db_field, request, **kwargs):
886             if db_field.name == "cars":
887                 kwargs["queryset"] = Car.objects.filter(owner=request.user)
888             return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
890 .. method:: ModelAdmin.formfield_for_choice_field(self, db_field, request, **kwargs)
892     Like the ``formfield_for_foreignkey`` and ``formfield_for_manytomany``
893     methods, the ``formfield_for_choice_field`` method can be overridden to
894     change the default formfield for a field that has declared choices. For
895     example, if the choices available to a superuser should be different than
896     those available to regular staff, you could proceed as follows::
898         class MyModelAdmin(admin.ModelAdmin):
899             def formfield_for_choice_field(self, db_field, request, **kwargs):
900                 if db_field.name == "status":
901                     kwargs['choices'] = (
902                         ('accepted', 'Accepted'),
903                         ('denied', 'Denied'),
904                     )
905                     if request.user.is_superuser:
906                         kwargs['choices'] += (('ready', 'Ready for deployment'),)
907                 return super(MyModelAdmin, self).formfield_for_choice_field(db_field, request, **kwargs)
909 .. method:: ModelAdmin.has_add_permission(self, request)
911     Should return ``True`` if adding an object is permitted, ``False``
912     otherwise.
914 .. method:: ModelAdmin.has_change_permission(self, request, obj=None)
916     Should return ``True`` if editing obj is permitted, ``False`` otherwise.
917     If obj is ``None``, should return ``True`` or ``False`` to indicate whether
918     editing of objects of this type is permitted in general (e.g., ``False``
919     will be interpreted as meaning that the current user is not permitted to
920     edit any object of this type).
922 .. method:: ModelAdmin.has_delete_permission(self, request, obj=None)
924     Should return ``True`` if deleting obj is permitted, ``False`` otherwise.
925     If obj is ``None``, should return ``True`` or ``False`` to indicate whether
926     deleting objects of this type is permitted in general (e.g., ``False`` will
927     be interpreted as meaning that the current user is not permitted to delete
928     any object of this type).
930 .. method:: ModelAdmin.queryset(self, request)
932 The ``queryset`` method on a ``ModelAdmin`` returns a
933 :class:`~django.db.models.QuerySet` of all model instances that can be
934 edited by the admin site. One use case for overriding this method is
935 to show objects owned by the logged-in user::
937     class MyModelAdmin(admin.ModelAdmin):
938         def queryset(self, request):
939             qs = super(MyModelAdmin, self).queryset(request)
940             if request.user.is_superuser:
941                 return qs
942             return qs.filter(author=request.user)
944 .. method:: ModelAdmin.message_user(request, message)
946     Sends a message to the user. The default implementation creates a message
947     using the :mod:`django.contrib.messages` backend. See the
948     :ref:`custom ModelAdmin example <custom-admin-action>`.
950 Other methods
951 ~~~~~~~~~~~~~
953 .. method:: ModelAdmin.add_view(self, request, form_url='', extra_context=None)
955 Django view for the model instance addition page. See note below.
957 .. method:: ModelAdmin.change_view(self, request, object_id, extra_context=None)
959 Django view for the model instance edition page. See note below.
961 .. method:: ModelAdmin.changelist_view(self, request, extra_context=None)
963 Django view for the model instances change list/actions page. See note below.
965 .. method:: ModelAdmin.delete_view(self, request, object_id, extra_context=None)
967 Django view for the model instance(s) deletion confirmation page. See note below.
969 .. method:: ModelAdmin.history_view(self, request, object_id, extra_context=None)
971 Django view for the page that shows the modification history for a given model
972 instance.
974 Unlike the hook-type ``ModelAdmin`` methods detailed in the previous section,
975 these five methods are in reality designed to be invoked as Django views from
976 the admin application URL dispatching handler to render the pages that deal
977 with model instances CRUD operations. As a result, completely overriding these
978 methods will significantly change the behavior of the admin application.
980 One common reason for overriding these methods is to augment the context data
981 that is provided to the template that renders the view. In the following
982 example, the change view is overridden so that the rendered template is
983 provided some extra mapping data that would not otherwise be available::
985     class MyModelAdmin(admin.ModelAdmin):
987         # A template for a very customized change view:
988         change_form_template = 'admin/myapp/extras/openstreetmap_change_form.html'
990         def get_osm_info(self):
991             # ...
993         def change_view(self, request, object_id, extra_context=None):
994             my_context = {
995                 'osm_data': self.get_osm_info(),
996             }
997             return super(MyModelAdmin, self).change_view(request, object_id,
998                 extra_context=my_context)
1000 ``ModelAdmin`` media definitions
1001 --------------------------------
1003 There are times where you would like add a bit of CSS and/or JavaScript to
1004 the add/change views. This can be accomplished by using a Media inner class
1005 on your ``ModelAdmin``::
1007     class ArticleAdmin(admin.ModelAdmin):
1008         class Media:
1009             css = {
1010                 "all": ("my_styles.css",)
1011             }
1012             js = ("my_code.js",)
1014 Keep in mind that this will be prepended with ``MEDIA_URL``. The same rules
1015 apply as :doc:`regular media definitions on forms </topics/forms/media>`.
1017 Django admin Javascript makes use of the `jQuery`_ library. To avoid
1018 conflict with user scripts, Django's jQuery is namespaced as
1019 ``django.jQuery``. If you want to use jQuery in your own admin
1020 JavaScript without including a second copy, you can use the
1021 ``django.jQuery`` object on changelist and add/edit views.
1023 .. _jQuery: http://jquery.com
1025 Adding custom validation to the admin
1026 -------------------------------------
1028 Adding custom validation of data in the admin is quite easy. The automatic admin
1029 interface reuses :mod:`django.forms`, and the ``ModelAdmin`` class gives you
1030 the ability define your own form::
1032     class ArticleAdmin(admin.ModelAdmin):
1033         form = MyArticleAdminForm
1035 ``MyArticleAdminForm`` can be defined anywhere as long as you import where
1036 needed. Now within your form you can add your own custom validation for
1037 any field::
1039     class MyArticleAdminForm(forms.ModelForm):
1040         class Meta:
1041             model = Article
1043         def clean_name(self):
1044             # do something that validates your data
1045             return self.cleaned_data["name"]
1047 It is important you use a ``ModelForm`` here otherwise things can break. See the
1048 :doc:`forms </ref/forms/index>` documentation on :doc:`custom validation
1049 </ref/forms/validation>` and, more specifically, the
1050 :ref:`model form validation notes <overriding-modelform-clean-method>` for more
1051 information.
1053 .. _admin-inlines:
1055 ``InlineModelAdmin`` objects
1056 ============================
1058 .. class:: InlineModelAdmin
1060 The admin interface has the ability to edit models on the same page as a
1061 parent model. These are called inlines. Suppose you have these two models::
1063      class Author(models.Model):
1064         name = models.CharField(max_length=100)
1066      class Book(models.Model):
1067         author = models.ForeignKey(Author)
1068         title = models.CharField(max_length=100)
1070 You can edit the books authored by an author on the author page. You add
1071 inlines to a model by specifying them in a ``ModelAdmin.inlines``::
1073     class BookInline(admin.TabularInline):
1074         model = Book
1076     class AuthorAdmin(admin.ModelAdmin):
1077         inlines = [
1078             BookInline,
1079         ]
1081 Django provides two subclasses of ``InlineModelAdmin`` and they are:
1083     * ``TabularInline``
1084     * ``StackedInline``
1086 The difference between these two is merely the template used to render them.
1088 ``InlineModelAdmin`` options
1089 -----------------------------
1091 The ``InlineModelAdmin`` class is a subclass of ``ModelAdmin`` so it inherits
1092 all the same functionality as well as some of its own:
1094 .. attribute:: InlineModelAdmin.model
1096     The model in which the inline is using. This is required.
1098 .. attribute:: InlineModelAdmin.fk_name
1100     The name of the foreign key on the model. In most cases this will be dealt
1101     with automatically, but ``fk_name`` must be specified explicitly if there
1102     are more than one foreign key to the same parent model.
1104 .. attribute:: InlineModelAdmin.formset
1106     This defaults to ``BaseInlineFormSet``. Using your own formset can give you
1107     many possibilities of customization. Inlines are built around
1108     :ref:`model formsets <model-formsets>`.
1110 .. attribute:: InlineModelAdmin.form
1112     The value for ``form`` defaults to ``ModelForm``. This is what is passed
1113     through to ``inlineformset_factory`` when creating the formset for this
1114     inline.
1116 .. _ref-contrib-admin-inline-extra:
1118 .. attribute:: InlineModelAdmin.extra
1121     This controls the number of extra forms the formset will display in addition
1122     to the initial forms. See the
1123     :doc:`formsets documentation </topics/forms/formsets>` for more information.
1125     .. versionadded:: 1.2
1127     For users with JavaScript-enabled browsers, an "Add another" link is
1128     provided to enable any number of additional inlines to be added in addition
1129     to those provided as a result of the ``extra`` argument.
1131     The dynamic link will not appear if the number of currently displayed forms
1132     exceeds ``max_num``, or if the user does not have JavaScript enabled.
1134 .. _ref-contrib-admin-inline-max-num:
1136 .. attribute:: InlineModelAdmin.max_num
1138     This controls the maximum number of forms to show in the inline. This
1139     doesn't directly correlate to the number of objects, but can if the value
1140     is small enough. See :ref:`model-formsets-max-num` for more information.
1142 .. attribute:: InlineModelAdmin.raw_id_fields
1144     By default, Django's admin uses a select-box interface (<select>) for
1145     fields that are ``ForeignKey``. Sometimes you don't want to incur the
1146     overhead of having to select all the related instances to display in the
1147     drop-down.
1149     ``raw_id_fields`` is a list of fields you would like to change into a
1150     ``Input`` widget for either a ``ForeignKey`` or ``ManyToManyField``::
1152         class BookInline(admin.TabularInline):
1153             model = Book
1154             raw_id_fields = ("pages",)
1157 .. attribute:: InlineModelAdmin.template
1159     The template used to render the inline on the page.
1161 .. attribute:: InlineModelAdmin.verbose_name
1163     An override to the ``verbose_name`` found in the model's inner ``Meta``
1164     class.
1166 .. attribute:: InlineModelAdmin.verbose_name_plural
1168     An override to the ``verbose_name_plural`` found in the model's inner
1169     ``Meta`` class.
1171 .. attribute:: InlineModelAdmin.can_delete
1173     Specifies whether or not inline objects can be deleted in the inline.
1174     Defaults to ``True``.
1177 Working with a model with two or more foreign keys to the same parent model
1178 ---------------------------------------------------------------------------
1180 It is sometimes possible to have more than one foreign key to the same model.
1181 Take this model for instance::
1183     class Friendship(models.Model):
1184         to_person = models.ForeignKey(Person, related_name="friends")
1185         from_person = models.ForeignKey(Person, related_name="from_friends")
1187 If you wanted to display an inline on the ``Person`` admin add/change pages
1188 you need to explicitly define the foreign key since it is unable to do so
1189 automatically::
1191     class FriendshipInline(admin.TabularInline):
1192         model = Friendship
1193         fk_name = "to_person"
1195     class PersonAdmin(admin.ModelAdmin):
1196         inlines = [
1197             FriendshipInline,
1198         ]
1200 Working with Many-to-Many Models
1201 --------------------------------
1203 .. versionadded:: 1.2
1205 By default, admin widgets for many-to-many relations will be displayed
1206 on whichever model contains the actual reference to the ``ManyToManyField``.
1207 Depending on your ``ModelAdmin`` definition, each many-to-many field in your
1208 model will be represented by a standard HTML ``<select multiple>``, a
1209 horizontal or vertical filter, or a ``raw_id_admin`` widget. However, it is
1210 also possible to to replace these widgets with inlines.
1212 Suppose we have the following models::
1214     class Person(models.Model):
1215         name = models.CharField(max_length=128)
1217     class Group(models.Model):
1218         name = models.CharField(max_length=128)
1219         members = models.ManyToManyField(Person, related_name='groups')
1221 If you want to display many-to-many relations using an inline, you can do
1222 so by defining an ``InlineModelAdmin`` object for the relationship::
1224     class MembershipInline(admin.TabularInline):
1225         model = Group.members.through
1227     class PersonAdmin(admin.ModelAdmin):
1228         inlines = [
1229             MembershipInline,
1230         ]
1232     class GroupAdmin(admin.ModelAdmin):
1233         inlines = [
1234             MembershipInline,
1235         ]
1236         exclude = ('members',)
1238 There are two features worth noting in this example.
1240 Firstly - the ``MembershipInline`` class references ``Group.members.through``.
1241 The ``through`` attribute is a reference to the model that manages the
1242 many-to-many relation. This model is automatically created by Django when you
1243 define a many-to-many field.
1245 Secondly, the ``GroupAdmin`` must manually exclude the ``members`` field.
1246 Django displays an admin widget for a many-to-many field on the model that
1247 defines the relation (in this case, ``Group``). If you want to use an inline
1248 model to represent the many-to-many relationship, you must tell Django's admin
1249 to *not* display this widget - otherwise you will end up with two widgets on
1250 your admin page for managing the relation.
1252 In all other respects, the ``InlineModelAdmin`` is exactly the same as any
1253 other. You can customize the appearance using any of the normal
1254 ``ModelAdmin`` properties.
1256 Working with Many-to-Many Intermediary Models
1257 ----------------------------------------------
1259 When you specify an intermediary model using the ``through`` argument to a
1260 ``ManyToManyField``, the admin will not display a widget by default. This is
1261 because each instance of that intermediary model requires more information
1262 than could be displayed in a single widget, and the layout required for
1263 multiple widgets will vary depending on the intermediate model.
1265 However, we still want to be able to edit that information inline. Fortunately,
1266 this is easy to do with inline admin models. Suppose we have the following
1267 models::
1269     class Person(models.Model):
1270         name = models.CharField(max_length=128)
1272     class Group(models.Model):
1273         name = models.CharField(max_length=128)
1274         members = models.ManyToManyField(Person, through='Membership')
1276     class Membership(models.Model):
1277         person = models.ForeignKey(Person)
1278         group = models.ForeignKey(Group)
1279         date_joined = models.DateField()
1280         invite_reason = models.CharField(max_length=64)
1282 The first step in displaying this intermediate model in the admin is to
1283 define an inline class for the ``Membership`` model::
1285     class MembershipInline(admin.TabularInline):
1286         model = Membership
1287         extra = 1
1289 This simple example uses the default ``InlineModelAdmin`` values for the
1290 ``Membership`` model, and limits the extra add forms to one. This could be
1291 customized using any of the options available to ``InlineModelAdmin`` classes.
1293 Now create admin views for the ``Person`` and ``Group`` models::
1295     class PersonAdmin(admin.ModelAdmin):
1296         inlines = (MembershipInline,)
1298     class GroupAdmin(admin.ModelAdmin):
1299         inlines = (MembershipInline,)
1301 Finally, register your ``Person`` and ``Group`` models with the admin site::
1303     admin.site.register(Person, PersonAdmin)
1304     admin.site.register(Group, GroupAdmin)
1306 Now your admin site is set up to edit ``Membership`` objects inline from
1307 either the ``Person`` or the ``Group`` detail pages.
1309 .. _using-generic-relations-as-an-inline:
1311 Using generic relations as an inline
1312 ------------------------------------
1314 It is possible to use an inline with generically related objects. Let's say
1315 you have the following models::
1317     class Image(models.Model):
1318         image = models.ImageField(upload_to="images")
1319         content_type = models.ForeignKey(ContentType)
1320         object_id = models.PositiveIntegerField()
1321         content_object = generic.GenericForeignKey("content_type", "object_id")
1323     class Product(models.Model):
1324         name = models.CharField(max_length=100)
1326 If you want to allow editing and creating ``Image`` instance on the ``Product``
1327 add/change views you can use ``GenericTabularInline`` or
1328 ``GenericStackedInline`` (both subclasses of ``GenericInlineModelAdmin``)
1329 provided by ``django.contrib.contenttypes.generic``, they implement tabular and
1330 stacked visual layouts for the forms representing the inline objects
1331 respectively just like their non-generic counterparts and behave just like any
1332 other inline. In your ``admin.py`` for this example app::
1334     from django.contrib import admin
1335     from django.contrib.contenttypes import generic
1337     from myproject.myapp.models import Image, Product
1339     class ImageInline(generic.GenericTabularInline):
1340         model = Image
1342     class ProductAdmin(admin.ModelAdmin):
1343         inlines = [
1344             ImageInline,
1345         ]
1347     admin.site.register(Product, ProductAdmin)
1349 See the :doc:`contenttypes documentation </ref/contrib/contenttypes>` for more
1350 specific information.
1352 Overriding Admin Templates
1353 ==========================
1355 It is relatively easy to override many of the templates which the admin module
1356 uses to generate the various pages of an admin site. You can even override a few
1357 of these templates for a specific app, or a specific model.
1359 Set up your projects admin template directories
1360 -----------------------------------------------
1362 The admin template files are located in the ``contrib/admin/templates/admin``
1363 directory.
1365 In order to override one or more of them, first create an ``admin`` directory in
1366 your project's ``templates`` directory. This can be any of the directories you
1367 specified in ``TEMPLATE_DIRS``.
1369 Within this ``admin`` directory, create sub-directories named after your app.
1370 Within these app subdirectories create sub-directories named after your models.
1371 Note, that the admin app will lowercase the model name when looking for the
1372 directory, so make sure you name the directory in all lowercase if you are going
1373 to run your app on a case-sensitive filesystem.
1375 To override an admin template for a specific app, copy and edit the template
1376 from the ``django/contrib/admin/templates/admin`` directory, and save it to one
1377 of the directories you just created.
1379 For example, if we wanted to add a tool to the change list view for all the
1380 models in an app named ``my_app``, we would copy
1381 ``contrib/admin/templates/admin/change_list.html`` to the
1382 ``templates/admin/my_app/`` directory of our project, and make any necessary
1383 changes.
1385 If we wanted to add a tool to the change list view for only a specific model
1386 named 'Page', we would copy that same file to the
1387 ``templates/admin/my_app/page`` directory of our project.
1389 Overriding vs. replacing an admin template
1390 ------------------------------------------
1392 Because of the modular design of the admin templates, it is usually neither
1393 necessary nor advisable to replace an entire template. It is almost always
1394 better to override only the section of the template which you need to change.
1396 To continue the example above, we want to add a new link next to the ``History``
1397 tool for the ``Page`` model. After looking at ``change_form.html`` we determine
1398 that we only need to override the ``object-tools`` block. Therefore here is our
1399 new ``change_form.html`` :
1401 .. code-block:: html+django
1403     {% extends "admin/change_form.html" %}
1404     {% load i18n %}
1405     {% block object-tools %}
1406     {% if change %}{% if not is_popup %}
1407       <ul class="object-tools">
1408         <li><a href="history/" class="historylink">{% trans "History" %}</a></li>
1409         <li><a href="mylink/" class="historylink">My Link</a></li>
1410         {% if has_absolute_url %}
1411             <li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">
1412                 {% trans "View on site" %}</a>
1413             </li>
1414         {% endif%}
1415       </ul>
1416     {% endif %}{% endif %}
1417     {% endblock %}
1419 And that's it! If we placed this file in the ``templates/admin/my_app``
1420 directory, our link would appear on every model's change form.
1422 Templates which may be overridden per app or model
1423 --------------------------------------------------
1425 Not every template in ``contrib/admin/templates/admin`` may be overridden per
1426 app or per model. The following can:
1428     * ``app_index.html``
1429     * ``change_form.html``
1430     * ``change_list.html``
1431     * ``delete_confirmation.html``
1432     * ``object_history.html``
1434 For those templates that cannot be overridden in this way, you may still
1435 override them for your entire project. Just place the new version in your
1436 ``templates/admin`` directory. This is particularly useful to create custom 404
1437 and 500 pages.
1439 .. note::
1441     Some of the admin templates, such as ``change_list_request.html`` are used
1442     to render custom inclusion tags. These may be overridden, but in such cases
1443     you are probably better off creating your own version of the tag in question
1444     and giving it a different name. That way you can use it selectively.
1446 Root and login templates
1447 ------------------------
1449 If you wish to change the index, login or logout templates, you are better off
1450 creating your own ``AdminSite`` instance (see below), and changing the
1451 :attr:`AdminSite.index_template` , :attr:`AdminSite.login_template` or
1452 :attr:`AdminSite.logout_template` properties.
1454 ``AdminSite`` objects
1455 =====================
1457 .. class:: AdminSite(name=None)
1459 A Django administrative site is represented by an instance of
1460 ``django.contrib.admin.sites.AdminSite``; by default, an instance of
1461 this class is created as ``django.contrib.admin.site`` and you can
1462 register your models and ``ModelAdmin`` instances with it.
1464 If you'd like to set up your own administrative site with custom
1465 behavior, however, you're free to subclass ``AdminSite`` and override
1466 or add anything you like. Then, simply create an instance of your
1467 ``AdminSite`` subclass (the same way you'd instantiate any other
1468 Python class), and register your models and ``ModelAdmin`` subclasses
1469 with it instead of using the default.
1471 .. versionadded:: 1.1
1473 When constructing an instance of an ``AdminSite``, you are able to provide
1474 a unique instance name using the ``name`` argument to the constructor. This
1475 instance name is used to identify the instance, especially when
1476 :ref:`reversing admin URLs <admin-reverse-urls>`. If no instance name is
1477 provided, a default instance name of ``admin`` will be used.
1479 ``AdminSite`` attributes
1480 ------------------------
1482 Templates can override or extend base admin templates as described in
1483 `Overriding Admin Templates`_.
1485 .. attribute:: AdminSite.index_template
1487 Path to a custom template that will be used by the admin site main index view.
1489 .. attribute:: AdminSite.login_template
1491 Path to a custom template that will be used by the admin site login view.
1493 .. attribute:: AdminSite.logout_template
1495 .. versionadded:: 1.2
1497 Path to a custom template that will be used by the admin site logout view.
1499 .. attribute:: AdminSite.password_change_template
1501 .. versionadded:: 1.2
1503 Path to a custom template that will be used by the admin site password change
1504 view.
1506 .. attribute:: AdminSite.password_change_done_template
1508 .. versionadded:: 1.2
1510 Path to a custom template that will be used by the admin site password change
1511 done view.
1513 Hooking ``AdminSite`` instances into your URLconf
1514 -------------------------------------------------
1516 The last step in setting up the Django admin is to hook your ``AdminSite``
1517 instance into your URLconf. Do this by pointing a given URL at the
1518 ``AdminSite.urls`` method.
1520 In this example, we register the default ``AdminSite`` instance
1521 ``django.contrib.admin.site`` at the URL ``/admin/`` ::
1523     # urls.py
1524     from django.conf.urls.defaults import *
1525     from django.contrib import admin
1527     admin.autodiscover()
1529     urlpatterns = patterns('',
1530         (r'^admin/', include(admin.site.urls)),
1531     )
1533 Above we used ``admin.autodiscover()`` to automatically load the
1534 ``INSTALLED_APPS`` admin.py modules.
1536 In this example, we register the ``AdminSite`` instance
1537 ``myproject.admin.admin_site`` at the URL ``/myadmin/`` ::
1539     # urls.py
1540     from django.conf.urls.defaults import *
1541     from myproject.admin import admin_site
1543     urlpatterns = patterns('',
1544         (r'^myadmin/', include(admin_site.urls)),
1545     )
1547 There is really no need to use autodiscover when using your own ``AdminSite``
1548 instance since you will likely be importing all the per-app admin.py modules
1549 in your ``myproject.admin`` module.
1551 Multiple admin sites in the same URLconf
1552 ----------------------------------------
1554 It's easy to create multiple instances of the admin site on the same
1555 Django-powered Web site. Just create multiple instances of ``AdminSite`` and
1556 root each one at a different URL.
1558 .. versionchanged:: 1.1
1559     The method for hooking ``AdminSite`` instances into urls has changed in
1560     Django 1.1.
1562 In this example, the URLs ``/basic-admin/`` and ``/advanced-admin/`` feature
1563 separate versions of the admin site -- using the ``AdminSite`` instances
1564 ``myproject.admin.basic_site`` and ``myproject.admin.advanced_site``,
1565 respectively::
1567     # urls.py
1568     from django.conf.urls.defaults import *
1569     from myproject.admin import basic_site, advanced_site
1571     urlpatterns = patterns('',
1572         (r'^basic-admin/', include(basic_site.urls)),
1573         (r'^advanced-admin/', include(advanced_site.urls)),
1574     )
1576 ``AdminSite`` instances take a single argument to their constructor, their
1577 name, which can be anything you like. This argument becomes the prefix to the
1578 URL names for the purposes of :ref:`reversing them<admin-reverse-urls>`. This
1579 is only necessary if you are using more than one ``AdminSite``.
1581 Adding views to admin sites
1582 ---------------------------
1584 .. versionadded:: 1.1
1586 Just like :class:`ModelAdmin`, :class:`AdminSite` provides a
1587 :meth:`~django.contrib.admin.ModelAdmin.get_urls()` method
1588 that can be overridden to define additional views for the site. To add
1589 a new view to your admin site, extend the base
1590 :meth:`~django.contrib.admin.ModelAdmin.get_urls()` method to include
1591 a pattern for your new view.
1593 .. note::
1594     Any view you render that uses the admin templates, or extends the base
1595     admin template, should provide the ``current_app`` argument to
1596     ``RequestContext`` or ``Context`` when rendering the template.  It should
1597     be set to either ``self.name`` if your view is on an ``AdminSite`` or
1598     ``self.admin_site.name`` if your view is on a ``ModelAdmin``.
1600 .. _admin-reverse-urls:
1602 Reversing Admin URLs
1603 ====================
1605 .. versionadded:: 1.1
1607 When an :class:`AdminSite` is deployed, the views provided by that site are
1608 accessible using Django's :ref:`URL reversing system <naming-url-patterns>`.
1610 The :class:`AdminSite` provides the following named URL patterns:
1612     ======================  ========================  =============
1613     Page                    URL name                  Parameters
1614     ======================  ========================  =============
1615     Index                   ``index``
1616     Logout                  ``logout``
1617     Password change         ``password_change``
1618     Password change done    ``password_change_done``
1619     i18n javascript         ``jsi18n``
1620     Application index page  ``app_list``              ``app_label``
1621     ======================  ========================  =============
1623 Each :class:`ModelAdmin` instance provides an additional set of named URLs:
1625     ======================  ===============================================   =============
1626     Page                    URL name                                          Parameters
1627     ======================  ===============================================   =============
1628     Changelist              ``{{ app_label }}_{{ model_name }}_changelist``
1629     Add                     ``{{ app_label }}_{{ model_name }}_add``
1630     History                 ``{{ app_label }}_{{ model_name }}_history``      ``object_id``
1631     Delete                  ``{{ app_label }}_{{ model_name }}_delete``       ``object_id``
1632     Change                  ``{{ app_label }}_{{ model_name }}_change``       ``object_id``
1633     ======================  ===============================================   =============
1635 These named URLs are registered with the application namespace ``admin``, and
1636 with an instance namespace corresponding to the name of the Site instance.
1638 So - if you wanted to get a reference to the Change view for a particular
1639 ``Choice`` object (from the polls application) in the default admin, you would
1640 call::
1642     >>> from django.core import urlresolvers
1643     >>> c = Choice.objects.get(...)
1644     >>> change_url = urlresolvers.reverse('admin:polls_choice_change', args=(c.id,))
1646 This will find the first registered instance of the admin application (whatever the instance
1647 name), and resolve to the view for changing ``poll.Choice`` instances in that instance.
1649 If you want to find a URL in a specific admin instance, provide the name of that instance
1650 as a ``current_app`` hint to the reverse call. For example, if you specifically wanted
1651 the admin view from the admin instance named ``custom``, you would need to call::
1653     >>> change_url = urlresolvers.reverse('custom:polls_choice_change', args=(c.id,))
1655 For more details, see the documentation on :ref:`reversing namespaced URLs
1656 <topics-http-reversing-url-namespaces>`.