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.
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."
24 There are six steps in activating the Django admin site:
26 1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS`
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
36 4. For each of those models, optionally create a ``ModelAdmin`` class that
37 encapsulates the customized admin functionality and options for that
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.
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 ======================
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):
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``
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.
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
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
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
131 A full example, taken from the ``django.contrib.flatpages.FlatPage`` model::
133 class FlatPageAdmin(admin.ModelAdmin):
136 'fields': ('url', 'title', 'content', 'sites')
138 ('Advanced options', {
139 'classes': ('collapse',),
140 'fields': ('enable_comments', 'registration_required', 'template_name')
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:
155 A tuple of field names to display in this fieldset. This key is
161 'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
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::
169 'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
172 .. versionadded:: 1.2
174 ``fields`` can contain values defined in
175 :attr:`ModelAdmin.readonly_fields` to be displayed as read-only.
178 A list containing extra CSS classes to apply to the fieldset.
183 'classes': ['wide', 'extrapretty'],
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.
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
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.
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
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
263 .. attribute:: ModelAdmin.list_display
265 Set ``list_display`` to control which fields are displayed on the change list
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
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
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
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
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.
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.
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
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
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.
499 Django will only honor the first element in the list/tuple; any others
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
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
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
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
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
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
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``
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.
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).
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
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},
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.
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
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
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
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):
809 urls = super(MyModelAdmin, self).get_urls()
810 my_urls = patterns('',
811 (r'^my_view/$', self.my_view)
813 return my_urls + urls
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
822 However, the ``self.my_view`` function registered above suffers from two
825 * It will *not* perform any permission checks, so it will be accessible to
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):
838 urls = super(MyModelAdmin, self).get_urls()
839 my_urls = patterns('',
840 (r'^my_view/$', self.admin_site.admin_view(self.my_view))
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'),
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``
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:
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>`.
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
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):
993 def change_view(self, request, object_id, extra_context=None):
995 'osm_data': self.get_osm_info(),
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):
1010 "all": ("my_styles.css",)
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
1039 class MyArticleAdminForm(forms.ModelForm):
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
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):
1076 class AuthorAdmin(admin.ModelAdmin):
1081 Django provides two subclasses of ``InlineModelAdmin`` and they are:
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
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
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):
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``
1166 .. attribute:: InlineModelAdmin.verbose_name_plural
1168 An override to the ``verbose_name_plural`` found in the model's inner
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
1191 class FriendshipInline(admin.TabularInline):
1193 fk_name = "to_person"
1195 class PersonAdmin(admin.ModelAdmin):
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):
1232 class GroupAdmin(admin.ModelAdmin):
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
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):
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):
1342 class ProductAdmin(admin.ModelAdmin):
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``
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
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" %}
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>
1416 {% endif %}{% endif %}
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
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
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
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/`` ::
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)),
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/`` ::
1540 from django.conf.urls.defaults import *
1541 from myproject.admin import admin_site
1543 urlpatterns = patterns('',
1544 (r'^myadmin/', include(admin_site.urls)),
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
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``,
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)),
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.
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 ====================== ======================== =============
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
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>`.