diff options
Diffstat (limited to 'parts/django/docs/ref/contrib/admin/index.txt')
-rw-r--r-- | parts/django/docs/ref/contrib/admin/index.txt | 1613 |
1 files changed, 0 insertions, 1613 deletions
diff --git a/parts/django/docs/ref/contrib/admin/index.txt b/parts/django/docs/ref/contrib/admin/index.txt deleted file mode 100644 index b99cfdc..0000000 --- a/parts/django/docs/ref/contrib/admin/index.txt +++ /dev/null @@ -1,1613 +0,0 @@ -===================== -The Django admin site -===================== - -.. module:: django.contrib.admin - :synopsis: Django's admin site. - -One of the most powerful parts of Django is the automatic admin interface. It -reads metadata in your model to provide a powerful and production-ready -interface that content producers can immediately use to start adding content to -the site. In this document, we discuss how to activate, use and customize -Django's admin interface. - -.. admonition:: Note - - The admin site has been refactored significantly since Django 0.96. This - document describes the newest version of the admin site, which allows for - much richer customization. If you follow the development of Django itself, - you may have heard this described as "newforms-admin." - -Overview -======== - -There are six steps in activating the Django admin site: - - 1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS` - setting. - - 2. Admin has two dependencies - ``django.contrib.auth`` and - ``django.contrib.contenttypes``. If these applications are not - in your :setting:`INSTALLED_APPS` list, add them. - - 3. Determine which of your application's models should be editable in the - admin interface. - - 4. For each of those models, optionally create a ``ModelAdmin`` class that - encapsulates the customized admin functionality and options for that - particular model. - - 5. Instantiate an ``AdminSite`` and tell it about each of your models and - ``ModelAdmin`` classes. - - 6. Hook the ``AdminSite`` instance into your URLconf. - -Other topics ------------- - -.. toctree:: - :maxdepth: 1 - - actions - admindocs - -.. seealso:: - - For information about serving the media files (images, JavaScript, and CSS) - associated with the admin in production, see :ref:`serving-media-files`. - -``ModelAdmin`` objects -====================== - -.. class:: ModelAdmin - -The ``ModelAdmin`` class is the representation of a model in the admin -interface. These are stored in a file named ``admin.py`` in your application. -Let's take a look at a very simple example of the ``ModelAdmin``:: - - from django.contrib import admin - from myproject.myapp.models import Author - - class AuthorAdmin(admin.ModelAdmin): - pass - admin.site.register(Author, AuthorAdmin) - -.. admonition:: Do you need a ``ModelAdmin`` object at all? - - In the preceding example, the ``ModelAdmin`` class doesn't define any - custom values (yet). As a result, the default admin interface will be - provided. If you are happy with the default admin interface, you don't - need to define a ``ModelAdmin`` object at all -- you can register the - model class without providing a ``ModelAdmin`` description. The - preceding example could be simplified to:: - - from django.contrib import admin - from myproject.myapp.models import Author - - admin.site.register(Author) - -``ModelAdmin`` Options ----------------------- - -The ``ModelAdmin`` is very flexible. It has several options for dealing with -customizing the interface. All options are defined on the ``ModelAdmin`` -subclass:: - - class AuthorAdmin(admin.ModelAdmin): - date_hierarchy = 'pub_date' - -.. attribute:: ModelAdmin.date_hierarchy - -Set ``date_hierarchy`` to the name of a ``DateField`` or ``DateTimeField`` in -your model, and the change list page will include a date-based drilldown -navigation by that field. - -Example:: - - date_hierarchy = 'pub_date' - -.. attribute:: ModelAdmin.form - -By default a ``ModelForm`` is dynamically created for your model. It is used -to create the form presented on both the add/change pages. You can easily -provide your own ``ModelForm`` to override any default form behavior on the -add/change pages. - -For an example see the section `Adding custom validation to the admin`_. - -.. attribute:: ModelAdmin.fieldsets - -Set ``fieldsets`` to control the layout of admin "add" and "change" pages. - -``fieldsets`` is a list of two-tuples, in which each two-tuple represents a -``<fieldset>`` on the admin form page. (A ``<fieldset>`` is a "section" of the -form.) - -The two-tuples are in the format ``(name, field_options)``, where ``name`` is a -string representing the title of the fieldset and ``field_options`` is a -dictionary of information about the fieldset, including a list of fields to be -displayed in it. - -A full example, taken from the ``django.contrib.flatpages.FlatPage`` model:: - - class FlatPageAdmin(admin.ModelAdmin): - fieldsets = ( - (None, { - 'fields': ('url', 'title', 'content', 'sites') - }), - ('Advanced options', { - 'classes': ('collapse',), - 'fields': ('enable_comments', 'registration_required', 'template_name') - }), - ) - -This results in an admin page that looks like: - - .. image:: _images/flatfiles_admin.png - -If ``fieldsets`` isn't given, Django will default to displaying each field -that isn't an ``AutoField`` and has ``editable=True``, in a single fieldset, -in the same order as the fields are defined in the model. - -The ``field_options`` dictionary can have the following keys: - - * ``fields`` - A tuple of field names to display in this fieldset. This key is - required. - - Example:: - - { - 'fields': ('first_name', 'last_name', 'address', 'city', 'state'), - } - - To display multiple fields on the same line, wrap those fields in - their own tuple. In this example, the ``first_name`` and ``last_name`` - fields will display on the same line:: - - { - 'fields': (('first_name', 'last_name'), 'address', 'city', 'state'), - } - - .. versionadded:: 1.2 - - ``fields`` can contain values defined in - :attr:`ModelAdmin.readonly_fields` to be displayed as read-only. - - * ``classes`` - A list containing extra CSS classes to apply to the fieldset. - - Example:: - - { - 'classes': ['wide', 'extrapretty'], - } - - Two useful classes defined by the default admin site stylesheet are - ``collapse`` and ``wide``. Fieldsets with the ``collapse`` style will - be initially collapsed in the admin and replaced with a small - "click to expand" link. Fieldsets with the ``wide`` style will be - given extra horizontal space. - - * ``description`` - A string of optional extra text to be displayed at the top of each - fieldset, under the heading of the fieldset. - - Note that this value is *not* HTML-escaped when it's displayed in - the admin interface. This lets you include HTML if you so desire. - Alternatively you can use plain text and - ``django.utils.html.escape()`` to escape any HTML special - characters. - -.. attribute:: ModelAdmin.fields - -Use this option as an alternative to ``fieldsets`` if the layout does not -matter and if you want to only show a subset of the available fields in the -form. For example, you could define a simpler version of the admin form for -the ``django.contrib.flatpages.FlatPage`` model as follows:: - - class FlatPageAdmin(admin.ModelAdmin): - fields = ('url', 'title', 'content') - -In the above example, only the fields 'url', 'title' and 'content' will be -displayed, sequentially, in the form. - -.. versionadded:: 1.2 - -``fields`` can contain values defined in :attr:`ModelAdmin.readonly_fields` -to be displayed as read-only. - -.. admonition:: Note - - This ``fields`` option should not be confused with the ``fields`` - dictionary key that is within the ``fieldsets`` option, as described in - the previous section. - -.. attribute:: ModelAdmin.exclude - -This attribute, if given, should be a list of field names to exclude from the -form. - -For example, let's consider the following model:: - - class Author(models.Model): - name = models.CharField(max_length=100) - title = models.CharField(max_length=3) - birth_date = models.DateField(blank=True, null=True) - -If you want a form for the ``Author`` model that includes only the ``name`` -and ``title`` fields, you would specify ``fields`` or ``exclude`` like this:: - - class AuthorAdmin(admin.ModelAdmin): - fields = ('name', 'title') - - class AuthorAdmin(admin.ModelAdmin): - exclude = ('birth_date',) - -Since the Author model only has three fields, ``name``, ``title``, and -``birth_date``, the forms resulting from the above declarations will contain -exactly the same fields. - -.. attribute:: ModelAdmin.filter_horizontal - -Use a nifty unobtrusive JavaScript "filter" interface instead of the -usability-challenged ``<select multiple>`` in the admin form. The value is a -list of fields that should be displayed as a horizontal filter interface. See -``filter_vertical`` to use a vertical interface. - -.. attribute:: ModelAdmin.filter_vertical - -Same as ``filter_horizontal``, but is a vertical display of the filter -interface. - -.. attribute:: ModelAdmin.list_display - -Set ``list_display`` to control which fields are displayed on the change list -page of the admin. - -Example:: - - list_display = ('first_name', 'last_name') - -If you don't set ``list_display``, the admin site will display a single column -that displays the ``__unicode__()`` representation of each object. - -You have four possible values that can be used in ``list_display``: - - * A field of the model. For example:: - - class PersonAdmin(admin.ModelAdmin): - list_display = ('first_name', 'last_name') - - * A callable that accepts one parameter for the model instance. For - example:: - - def upper_case_name(obj): - return ("%s %s" % (obj.first_name, obj.last_name)).upper() - upper_case_name.short_description = 'Name' - - class PersonAdmin(admin.ModelAdmin): - list_display = (upper_case_name,) - - * A string representing an attribute on the ``ModelAdmin``. This behaves - same as the callable. For example:: - - class PersonAdmin(admin.ModelAdmin): - list_display = ('upper_case_name',) - - def upper_case_name(self, obj): - return ("%s %s" % (obj.first_name, obj.last_name)).upper() - upper_case_name.short_description = 'Name' - - * A string representing an attribute on the model. This behaves almost - the same as the callable, but ``self`` in this context is the model - instance. Here's a full model example:: - - class Person(models.Model): - name = models.CharField(max_length=50) - birthday = models.DateField() - - def decade_born_in(self): - return self.birthday.strftime('%Y')[:3] + "0's" - decade_born_in.short_description = 'Birth decade' - - class PersonAdmin(admin.ModelAdmin): - list_display = ('name', 'decade_born_in') - -A few special cases to note about ``list_display``: - - * If the field is a ``ForeignKey``, Django will display the - ``__unicode__()`` of the related object. - - * ``ManyToManyField`` fields aren't supported, because that would entail - executing a separate SQL statement for each row in the table. If you - want to do this nonetheless, give your model a custom method, and add - that method's name to ``list_display``. (See below for more on custom - methods in ``list_display``.) - - * If the field is a ``BooleanField`` or ``NullBooleanField``, Django will - display a pretty "on" or "off" icon instead of ``True`` or ``False``. - - * If the string given is a method of the model, ``ModelAdmin`` or a - callable, Django will HTML-escape the output by default. If you'd rather - not escape the output of the method, give the method an ``allow_tags`` - attribute whose value is ``True``. - - Here's a full example model:: - - class Person(models.Model): - first_name = models.CharField(max_length=50) - last_name = models.CharField(max_length=50) - color_code = models.CharField(max_length=6) - - def colored_name(self): - return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name) - colored_name.allow_tags = True - - class PersonAdmin(admin.ModelAdmin): - list_display = ('first_name', 'last_name', 'colored_name') - - * If the string given is a method of the model, ``ModelAdmin`` or a - callable that returns True or False Django will display a pretty "on" or - "off" icon if you give the method a ``boolean`` attribute whose value is - ``True``. - - Here's a full example model:: - - class Person(models.Model): - first_name = models.CharField(max_length=50) - birthday = models.DateField() - - def born_in_fifties(self): - return self.birthday.strftime('%Y')[:3] == '195' - born_in_fifties.boolean = True - - class PersonAdmin(admin.ModelAdmin): - list_display = ('name', 'born_in_fifties') - - - * The ``__str__()`` and ``__unicode__()`` methods are just as valid in - ``list_display`` as any other model method, so it's perfectly OK to do - this:: - - list_display = ('__unicode__', 'some_other_field') - - * Usually, elements of ``list_display`` that aren't actual database fields - can't be used in sorting (because Django does all the sorting at the - database level). - - However, if an element of ``list_display`` represents a certain database - field, you can indicate this fact by setting the ``admin_order_field`` - attribute of the item. - - For example:: - - class Person(models.Model): - first_name = models.CharField(max_length=50) - color_code = models.CharField(max_length=6) - - def colored_first_name(self): - return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name) - colored_first_name.allow_tags = True - colored_first_name.admin_order_field = 'first_name' - - class PersonAdmin(admin.ModelAdmin): - list_display = ('first_name', 'colored_first_name') - - The above will tell Django to order by the ``first_name`` field when - trying to sort by ``colored_first_name`` in the admin. - -.. attribute:: ModelAdmin.list_display_links - -Set ``list_display_links`` to control which fields in ``list_display`` should -be linked to the "change" page for an object. - -By default, the change list page will link the first column -- the first field -specified in ``list_display`` -- to the change page for each item. But -``list_display_links`` lets you change which columns are linked. Set -``list_display_links`` to a list or tuple of field names (in the same format as -``list_display``) to link. - -``list_display_links`` can specify one or many field names. As long as the -field names appear in ``list_display``, Django doesn't care how many (or how -few) fields are linked. The only requirement is: If you want to use -``list_display_links``, you must define ``list_display``. - -In this example, the ``first_name`` and ``last_name`` fields will be linked on -the change list page:: - - class PersonAdmin(admin.ModelAdmin): - list_display = ('first_name', 'last_name', 'birthday') - list_display_links = ('first_name', 'last_name') - -.. _admin-list-editable: - -.. attribute:: ModelAdmin.list_editable - -.. versionadded:: 1.1 - -Set ``list_editable`` to a list of field names on the model which will allow -editing on the change list page. That is, fields listed in ``list_editable`` -will be displayed as form widgets on the change list page, allowing users to -edit and save multiple rows at once. - -.. note:: - - ``list_editable`` interacts with a couple of other options in particular - ways; you should note the following rules: - - * Any field in ``list_editable`` must also be in ``list_display``. You - can't edit a field that's not displayed! - - * The same field can't be listed in both ``list_editable`` and - ``list_display_links`` -- a field can't be both a form and a link. - - You'll get a validation error if either of these rules are broken. - -.. attribute:: ModelAdmin.list_filter - -Set ``list_filter`` to activate filters in the right sidebar of the change list -page of the admin. This should be a list of field names, and each specified -field should be either a ``BooleanField``, ``CharField``, ``DateField``, -``DateTimeField``, ``IntegerField`` or ``ForeignKey``. - -This example, taken from the ``django.contrib.auth.models.User`` model, shows -how both ``list_display`` and ``list_filter`` work:: - - class UserAdmin(admin.ModelAdmin): - list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff') - list_filter = ('is_staff', 'is_superuser') - -The above code results in an admin change list page that looks like this: - - .. image:: _images/users_changelist.png - -(This example also has ``search_fields`` defined. See below.) - -.. attribute:: ModelAdmin.list_per_page - -Set ``list_per_page`` to control how many items appear on each paginated admin -change list page. By default, this is set to ``100``. - -.. attribute:: ModelAdmin.list_select_related - -Set ``list_select_related`` to tell Django to use -:meth:`~django.db.models.QuerySet.select_related` in retrieving the list of -objects on the admin change list page. This can save you a bunch of database -queries. - -The value should be either ``True`` or ``False``. Default is ``False``. - -Note that Django will use :meth:`~django.db.models.QuerySet.select_related`, -regardless of this setting, if one of the ``list_display`` fields is a -``ForeignKey``. - -.. attribute:: ModelAdmin.inlines - -See ``InlineModelAdmin`` objects below. - -.. attribute:: ModelAdmin.ordering - -Set ``ordering`` to specify how objects on the admin change list page should be -ordered. This should be a list or tuple in the same format as a model's -``ordering`` parameter. - -If this isn't provided, the Django admin will use the model's default ordering. - -.. admonition:: Note - - Django will only honor the first element in the list/tuple; any others - will be ignored. - -.. attribute:: ModelAdmin.prepopulated_fields - -Set ``prepopulated_fields`` to a dictionary mapping field names to the fields -it should prepopulate from:: - - class ArticleAdmin(admin.ModelAdmin): - prepopulated_fields = {"slug": ("title",)} - -When set, the given fields will use a bit of JavaScript to populate from the -fields assigned. The main use for this functionality is to automatically -generate the value for ``SlugField`` fields from one or more other fields. The -generated value is produced by concatenating the values of the source fields, -and then by transforming that result into a valid slug (e.g. substituting -dashes for spaces). - -``prepopulated_fields`` doesn't accept ``DateTimeField``, ``ForeignKey``, nor -``ManyToManyField`` fields. - -.. attribute:: ModelAdmin.radio_fields - -By default, Django's admin uses a select-box interface (<select>) for -fields that are ``ForeignKey`` or have ``choices`` set. If a field is present -in ``radio_fields``, Django will use a radio-button interface instead. -Assuming ``group`` is a ``ForeignKey`` on the ``Person`` model:: - - class PersonAdmin(admin.ModelAdmin): - radio_fields = {"group": admin.VERTICAL} - -You have the choice of using ``HORIZONTAL`` or ``VERTICAL`` from the -``django.contrib.admin`` module. - -Don't include a field in ``radio_fields`` unless it's a ``ForeignKey`` or has -``choices`` set. - -.. attribute:: ModelAdmin.raw_id_fields - -By default, Django's admin uses a select-box interface (<select>) for -fields that are ``ForeignKey``. Sometimes you don't want to incur the -overhead of having to select all the related instances to display in the -drop-down. - -``raw_id_fields`` is a list of fields you would like to change -into a ``Input`` widget for either a ``ForeignKey`` or ``ManyToManyField``:: - - class ArticleAdmin(admin.ModelAdmin): - raw_id_fields = ("newspaper",) - -.. attribute:: ModelAdmin.readonly_fields - -.. versionadded:: 1.2 - -By default the admin shows all fields as editable. Any fields in this option -(which should be a ``list`` or ``tuple``) will display its data as-is and -non-editable. This option behaves nearly identical to :attr:`ModelAdmin.list_display`. -Usage is the same, however, when you specify :attr:`ModelAdmin.fields` or -:attr:`ModelAdmin.fieldsets` the read-only fields must be present to be shown -(they are ignored otherwise). - -If ``readonly_fields`` is used without defining explicit ordering through -:attr:`ModelAdmin.fields` or :attr:`ModelAdmin.fieldsets` they will be added -last after all editable fields. - -.. attribute:: ModelAdmin.save_as - -Set ``save_as`` to enable a "save as" feature on admin change forms. - -Normally, objects have three save options: "Save", "Save and continue editing" -and "Save and add another". If ``save_as`` is ``True``, "Save and add another" -will be replaced by a "Save as" button. - -"Save as" means the object will be saved as a new object (with a new ID), -rather than the old object. - -By default, ``save_as`` is set to ``False``. - -.. attribute:: ModelAdmin.save_on_top - -Set ``save_on_top`` to add save buttons across the top of your admin change -forms. - -Normally, the save buttons appear only at the bottom of the forms. If you set -``save_on_top``, the buttons will appear both on the top and the bottom. - -By default, ``save_on_top`` is set to ``False``. - -.. attribute:: ModelAdmin.search_fields - -Set ``search_fields`` to enable a search box on the admin change list page. -This should be set to a list of field names that will be searched whenever -somebody submits a search query in that text box. - -These fields should be some kind of text field, such as ``CharField`` or -``TextField``. You can also perform a related lookup on a ``ForeignKey`` or -``ManyToManyField`` with the lookup API "follow" notation:: - - search_fields = ['foreign_key__related_fieldname'] - -For example, if you have a blog entry with an author, the following definition -would enable search blog entries by the email address of the author:: - - search_fields = ['user__email'] - -When somebody does a search in the admin search box, Django splits the search -query into words and returns all objects that contain each of the words, case -insensitive, where each word must be in at least one of ``search_fields``. For -example, if ``search_fields`` is set to ``['first_name', 'last_name']`` and a -user searches for ``john lennon``, Django will do the equivalent of this SQL -``WHERE`` clause:: - - WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%') - AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%') - -For faster and/or more restrictive searches, prefix the field name -with an operator: - -``^`` - Matches the beginning of the field. For example, if ``search_fields`` is - set to ``['^first_name', '^last_name']`` and a user searches for - ``john lennon``, Django will do the equivalent of this SQL ``WHERE`` - clause:: - - WHERE (first_name ILIKE 'john%' OR last_name ILIKE 'john%') - AND (first_name ILIKE 'lennon%' OR last_name ILIKE 'lennon%') - - This query is more efficient than the normal ``'%john%'`` query, because - the database only needs to check the beginning of a column's data, rather - than seeking through the entire column's data. Plus, if the column has an - index on it, some databases may be able to use the index for this query, - even though it's a ``LIKE`` query. - -``=`` - Matches exactly, case-insensitive. For example, if - ``search_fields`` is set to ``['=first_name', '=last_name']`` and - a user searches for ``john lennon``, Django will do the equivalent - of this SQL ``WHERE`` clause:: - - WHERE (first_name ILIKE 'john' OR last_name ILIKE 'john') - AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon') - - Note that the query input is split by spaces, so, following this example, - it's currently not possible to search for all records in which - ``first_name`` is exactly ``'john winston'`` (containing a space). - -``@`` - Performs a full-text match. This is like the default search method but uses - an index. Currently this is only available for MySQL. - -.. attribute:: ModelAdmin.formfield_overrides - -.. versionadded:: 1.1 - -This provides a quick-and-dirty way to override some of the -:class:`~django.forms.Field` options for use in the admin. -``formfield_overrides`` is a dictionary mapping a field class to a dict of -arguments to pass to the field at construction time. - -Since that's a bit abstract, let's look at a concrete example. The most common -use of ``formfield_overrides`` is to add a custom widget for a certain type of -field. So, imagine we've written a ``RichTextEditorWidget`` that we'd like to -use for large text fields instead of the default ``<textarea>``. Here's how we'd -do that:: - - from django.db import models - from django.contrib import admin - - # Import our custom widget and our model from where they're defined - from myapp.widgets import RichTextEditorWidget - from myapp.models import MyModel - - class MyModelAdmin(admin.ModelAdmin): - formfield_overrides = { - models.TextField: {'widget': RichTextEditorWidget}, - } - -Note that the key in the dictionary is the actual field class, *not* a string. -The value is another dictionary; these arguments will be passed to -:meth:`~django.forms.Field.__init__`. See :doc:`/ref/forms/api` for details. - -.. warning:: - - If you want to use a custom widget with a relation field (i.e. - :class:`~django.db.models.ForeignKey` or - :class:`~django.db.models.ManyToManyField`), make sure you haven't included - that field's name in ``raw_id_fields`` or ``radio_fields``. - - ``formfield_overrides`` won't let you change the widget on relation fields - that have ``raw_id_fields`` or ``radio_fields`` set. That's because - ``raw_id_fields`` and ``radio_fields`` imply custom widgets of their own. - -.. attribute:: ModelAdmin.actions - -.. versionadded:: 1.1 - -A list of actions to make available on the change list page. See -:doc:`/ref/contrib/admin/actions` for details. - -.. attribute:: ModelAdmin.actions_on_top -.. attribute:: ModelAdmin.actions_on_bottom - -.. versionadded:: 1.1 - -Controls where on the page the actions bar appears. By default, the admin -changelist displays actions at the top of the page (``actions_on_top = True; -actions_on_bottom = False``). - -.. attribute:: ModelAdmin.actions_selection_counter - -.. versionadded:: 1.2 - -Controls whether a selection counter is display next to the action dropdown. -By default, the admin changelist will display it -(``actions_selection_counter = True``). - -Custom template options -~~~~~~~~~~~~~~~~~~~~~~~ - -The `Overriding Admin Templates`_ section describes how to override or extend -the default admin templates. Use the following options to override the default -templates used by the :class:`ModelAdmin` views: - -.. attribute:: ModelAdmin.add_form_template - - .. versionadded:: 1.2 - - Path to a custom template, used by :meth:`add_view`. - -.. attribute:: ModelAdmin.change_form_template - - Path to a custom template, used by :meth:`change_view`. - -.. attribute:: ModelAdmin.change_list_template - - Path to a custom template, used by :meth:`changelist_view`. - -.. attribute:: ModelAdmin.delete_confirmation_template - - Path to a custom template, used by :meth:`delete_view` for displaying a - confirmation page when deleting one or more objects. - -.. attribute:: ModelAdmin.delete_selected_confirmation_template - - .. versionadded:: 1.2 - - Path to a custom template, used by the :meth:`delete_selected` - action method for displaying a confirmation page when deleting one - or more objects. See the :doc:`actions - documentation</ref/contrib/admin/actions>`. - -.. attribute:: ModelAdmin.object_history_template - - Path to a custom template, used by :meth:`history_view`. - - -.. _model-admin-methods: - -``ModelAdmin`` methods ----------------------- - -.. method:: ModelAdmin.save_model(self, request, obj, form, change) - -The ``save_model`` method is given the ``HttpRequest``, a model instance, -a ``ModelForm`` instance and a boolean value based on whether it is adding or -changing the object. Here you can do any pre- or post-save operations. - -For example to attach ``request.user`` to the object prior to saving:: - - class ArticleAdmin(admin.ModelAdmin): - def save_model(self, request, obj, form, change): - obj.user = request.user - obj.save() - -.. method:: ModelAdmin.save_formset(self, request, form, formset, change) - -The ``save_formset`` method is given the ``HttpRequest``, the parent -``ModelForm`` instance and a boolean value based on whether it is adding or -changing the parent object. - -For example to attach ``request.user`` to each changed formset -model instance:: - - class ArticleAdmin(admin.ModelAdmin): - def save_formset(self, request, form, formset, change): - instances = formset.save(commit=False) - for instance in instances: - instance.user = request.user - instance.save() - formset.save_m2m() - -.. method:: ModelAdmin.get_readonly_fields(self, request, obj=None) - -.. versionadded:: 1.2 - -The ``get_readonly_fields`` method is given the ``HttpRequest`` and the -``obj`` being edited (or ``None`` on an add form) and is expected to return a -``list`` or ``tuple`` of field names that will be displayed as read-only, as -described above in the :attr:`ModelAdmin.readonly_fields` section. - -.. method:: ModelAdmin.get_urls(self) - -.. versionadded:: 1.1 - -The ``get_urls`` method on a ``ModelAdmin`` returns the URLs to be used for -that ModelAdmin in the same way as a URLconf. Therefore you can extend them as -documented in :doc:`/topics/http/urls`:: - - class MyModelAdmin(admin.ModelAdmin): - def get_urls(self): - urls = super(MyModelAdmin, self).get_urls() - my_urls = patterns('', - (r'^my_view/$', self.my_view) - ) - return my_urls + urls - -.. note:: - - Notice that the custom patterns are included *before* the regular admin - URLs: the admin URL patterns are very permissive and will match nearly - anything, so you'll usually want to prepend your custom URLs to the built-in - ones. - -However, the ``self.my_view`` function registered above suffers from two -problems: - - * It will *not* perform any permission checks, so it will be accessible to - the general public. - * It will *not* provide any header details to prevent caching. This means if - the page retrieves data from the database, and caching middleware is - active, the page could show outdated information. - -Since this is usually not what you want, Django provides a convenience wrapper -to check permissions and mark the view as non-cacheable. This wrapper is -:meth:`AdminSite.admin_view` (i.e. ``self.admin_site.admin_view`` inside a -``ModelAdmin`` instance); use it like so:: - - class MyModelAdmin(admin.ModelAdmin): - def get_urls(self): - urls = super(MyModelAdmin, self).get_urls() - my_urls = patterns('', - (r'^my_view/$', self.admin_site.admin_view(self.my_view)) - ) - return my_urls + urls - -Notice the wrapped view in the fifth line above:: - - (r'^my_view/$', self.admin_site.admin_view(self.my_view)) - -This wrapping will protect ``self.my_view`` from unauthorized access and will -apply the ``django.views.decorators.cache.never_cache`` decorator to make sure -it is not cached if the cache middleware is active. - -If the page is cacheable, but you still want the permission check to be performed, -you can pass a ``cacheable=True`` argument to :meth:`AdminSite.admin_view`:: - - (r'^my_view/$', self.admin_site.admin_view(self.my_view, cacheable=True)) - -.. method:: ModelAdmin.formfield_for_foreignkey(self, db_field, request, **kwargs) - -.. versionadded:: 1.1 - -The ``formfield_for_foreignkey`` method on a ``ModelAdmin`` allows you to -override the default formfield for a foreign key field. For example, to -return a subset of objects for this foreign key field based on the user:: - - class MyModelAdmin(admin.ModelAdmin): - def formfield_for_foreignkey(self, db_field, request, **kwargs): - if db_field.name == "car": - kwargs["queryset"] = Car.objects.filter(owner=request.user) - return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) - -This uses the ``HttpRequest`` instance to filter the ``Car`` foreign key field -to only display the cars owned by the ``User`` instance. - -.. method:: ModelAdmin.formfield_for_manytomany(self, db_field, request, **kwargs) - -.. versionadded:: 1.1 - -Like the ``formfield_for_foreignkey`` method, the ``formfield_for_manytomany`` -method can be overridden to change the default formfield for a many to many -field. For example, if an owner can own multiple cars and cars can belong -to multiple owners -- a many to many relationship -- you could filter the -``Car`` foreign key field to only display the cars owned by the ``User``:: - - class MyModelAdmin(admin.ModelAdmin): - def formfield_for_manytomany(self, db_field, request, **kwargs): - if db_field.name == "cars": - kwargs["queryset"] = Car.objects.filter(owner=request.user) - return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs) - -.. method:: ModelAdmin.queryset(self, request) - -The ``queryset`` method on a ``ModelAdmin`` returns a -:class:`~django.db.models.QuerySet` of all model instances that can be -edited by the admin site. One use case for overriding this method is -to show objects owned by the logged-in user:: - - class MyModelAdmin(admin.ModelAdmin): - def queryset(self, request): - qs = super(MyModelAdmin, self).queryset(request) - if request.user.is_superuser: - return qs - return qs.filter(author=request.user) - -.. method:: ModelAdmin.message_user(request, message) - - Sends a message to the user. The default implementation creates a message - using the :mod:`django.contrib.messages` backend. See the - :ref:`custom ModelAdmin example <custom-admin-action>`. - -Other methods -~~~~~~~~~~~~~ - -.. method:: ModelAdmin.add_view(self, request, form_url='', extra_context=None) - -Django view for the model instance addition page. See note below. - -.. method:: ModelAdmin.change_view(self, request, object_id, extra_context=None) - -Django view for the model instance edition page. See note below. - -.. method:: ModelAdmin.changelist_view(self, request, extra_context=None) - -Django view for the model instances change list/actions page. See note below. - -.. method:: ModelAdmin.delete_view(self, request, object_id, extra_context=None) - -Django view for the model instance(s) deletion confirmation page. See note below. - -.. method:: ModelAdmin.history_view(self, request, object_id, extra_context=None) - -Django view for the page that shows the modification history for a given model -instance. - -Unlike the hook-type ``ModelAdmin`` methods detailed in the previous section, -these five methods are in reality designed to be invoked as Django views from -the admin application URL dispatching handler to render the pages that deal -with model instances CRUD operations. As a result, completely overriding these -methods will significantly change the behavior of the admin application. - -One common reason for overriding these methods is to augment the context data -that is provided to the template that renders the view. In the following -example, the change view is overridden so that the rendered template is -provided some extra mapping data that would not otherwise be available:: - - class MyModelAdmin(admin.ModelAdmin): - - # A template for a very customized change view: - change_form_template = 'admin/myapp/extras/openstreetmap_change_form.html' - - def get_osm_info(self): - # ... - - def change_view(self, request, object_id, extra_context=None): - my_context = { - 'osm_data': self.get_osm_info(), - } - return super(MyModelAdmin, self).change_view(request, object_id, - extra_context=my_context) - -``ModelAdmin`` media definitions --------------------------------- - -There are times where you would like add a bit of CSS and/or JavaScript to -the add/change views. This can be accomplished by using a Media inner class -on your ``ModelAdmin``:: - - class ArticleAdmin(admin.ModelAdmin): - class Media: - css = { - "all": ("my_styles.css",) - } - js = ("my_code.js",) - -Keep in mind that this will be prepended with ``MEDIA_URL``. The same rules -apply as :doc:`regular media definitions on forms </topics/forms/media>`. - -Django admin Javascript makes use of the `jQuery`_ library. To avoid -conflict with user scripts, Django's jQuery is namespaced as -``django.jQuery``. If you want to use jQuery in your own admin -JavaScript without including a second copy, you can use the -``django.jQuery`` object on changelist and add/edit views. - -.. _jQuery: http://jquery.com - -Adding custom validation to the admin -------------------------------------- - -Adding custom validation of data in the admin is quite easy. The automatic admin -interface reuses :mod:`django.forms`, and the ``ModelAdmin`` class gives you -the ability define your own form:: - - class ArticleAdmin(admin.ModelAdmin): - form = MyArticleAdminForm - -``MyArticleAdminForm`` can be defined anywhere as long as you import where -needed. Now within your form you can add your own custom validation for -any field:: - - class MyArticleAdminForm(forms.ModelForm): - class Meta: - model = Article - - def clean_name(self): - # do something that validates your data - return self.cleaned_data["name"] - -It is important you use a ``ModelForm`` here otherwise things can break. See the -:doc:`forms </ref/forms/index>` documentation on :doc:`custom validation -</ref/forms/validation>` and, more specifically, the -:ref:`model form validation notes <overriding-modelform-clean-method>` for more -information. - -.. _admin-inlines: - -``InlineModelAdmin`` objects -============================ - -.. class:: InlineModelAdmin - -The admin interface has the ability to edit models on the same page as a -parent model. These are called inlines. Suppose you have these two models:: - - class Author(models.Model): - name = models.CharField(max_length=100) - - class Book(models.Model): - author = models.ForeignKey(Author) - title = models.CharField(max_length=100) - -You can edit the books authored by an author on the author page. You add -inlines to a model by specifying them in a ``ModelAdmin.inlines``:: - - class BookInline(admin.TabularInline): - model = Book - - class AuthorAdmin(admin.ModelAdmin): - inlines = [ - BookInline, - ] - -Django provides two subclasses of ``InlineModelAdmin`` and they are: - - * ``TabularInline`` - * ``StackedInline`` - -The difference between these two is merely the template used to render them. - -``InlineModelAdmin`` options ------------------------------ - -The ``InlineModelAdmin`` class is a subclass of ``ModelAdmin`` so it inherits -all the same functionality as well as some of its own: - -.. attribute:: InlineModelAdmin.model - - The model in which the inline is using. This is required. - -.. attribute:: InlineModelAdmin.fk_name - - The name of the foreign key on the model. In most cases this will be dealt - with automatically, but ``fk_name`` must be specified explicitly if there - are more than one foreign key to the same parent model. - -.. attribute:: InlineModelAdmin.formset - - This defaults to ``BaseInlineFormSet``. Using your own formset can give you - many possibilities of customization. Inlines are built around - :ref:`model formsets <model-formsets>`. - -.. attribute:: InlineModelAdmin.form - - The value for ``form`` defaults to ``ModelForm``. This is what is passed - through to ``inlineformset_factory`` when creating the formset for this - inline. - -.. _ref-contrib-admin-inline-extra: - -.. attribute:: InlineModelAdmin.extra - - - This controls the number of extra forms the formset will display in addition - to the initial forms. See the - :doc:`formsets documentation </topics/forms/formsets>` for more information. - - .. versionadded:: 1.2 - - For users with JavaScript-enabled browsers, an "Add another" link is - provided to enable any number of additional inlines to be added in addition - to those provided as a result of the ``extra`` argument. - - The dynamic link will not appear if the number of currently displayed forms - exceeds ``max_num``, or if the user does not have JavaScript enabled. - -.. _ref-contrib-admin-inline-max-num: - -.. attribute:: InlineModelAdmin.max_num - - This controls the maximum number of forms to show in the inline. This - doesn't directly correlate to the number of objects, but can if the value - is small enough. See :ref:`model-formsets-max-num` for more information. - -.. attribute:: InlineModelAdmin.raw_id_fields - - By default, Django's admin uses a select-box interface (<select>) for - fields that are ``ForeignKey``. Sometimes you don't want to incur the - overhead of having to select all the related instances to display in the - drop-down. - - ``raw_id_fields`` is a list of fields you would like to change into a - ``Input`` widget for either a ``ForeignKey`` or ``ManyToManyField``:: - - class BookInline(admin.TabularInline): - model = Book - raw_id_fields = ("pages",) - - -.. attribute:: InlineModelAdmin.template - - The template used to render the inline on the page. - -.. attribute:: InlineModelAdmin.verbose_name - - An override to the ``verbose_name`` found in the model's inner ``Meta`` - class. - -.. attribute:: InlineModelAdmin.verbose_name_plural - - An override to the ``verbose_name_plural`` found in the model's inner - ``Meta`` class. - -.. attribute:: InlineModelAdmin.can_delete - - Specifies whether or not inline objects can be deleted in the inline. - Defaults to ``True``. - - -Working with a model with two or more foreign keys to the same parent model ---------------------------------------------------------------------------- - -It is sometimes possible to have more than one foreign key to the same model. -Take this model for instance:: - - class Friendship(models.Model): - to_person = models.ForeignKey(Person, related_name="friends") - from_person = models.ForeignKey(Person, related_name="from_friends") - -If you wanted to display an inline on the ``Person`` admin add/change pages -you need to explicitly define the foreign key since it is unable to do so -automatically:: - - class FriendshipInline(admin.TabularInline): - model = Friendship - fk_name = "to_person" - - class PersonAdmin(admin.ModelAdmin): - inlines = [ - FriendshipInline, - ] - -Working with Many-to-Many Models --------------------------------- - -.. versionadded:: 1.2 - -By default, admin widgets for many-to-many relations will be displayed -on whichever model contains the actual reference to the ``ManyToManyField``. -Depending on your ``ModelAdmin`` definition, each many-to-many field in your -model will be represented by a standard HTML ``<select multiple>``, a -horizontal or vertical filter, or a ``raw_id_admin`` widget. However, it is -also possible to to replace these widgets with inlines. - -Suppose we have the following models:: - - class Person(models.Model): - name = models.CharField(max_length=128) - - class Group(models.Model): - name = models.CharField(max_length=128) - members = models.ManyToManyField(Person, related_name='groups') - -If you want to display many-to-many relations using an inline, you can do -so by defining an ``InlineModelAdmin`` object for the relationship:: - - class MembershipInline(admin.TabularInline): - model = Group.members.through - - class PersonAdmin(admin.ModelAdmin): - inlines = [ - MembershipInline, - ] - - class GroupAdmin(admin.ModelAdmin): - inlines = [ - MembershipInline, - ] - exclude = ('members',) - -There are two features worth noting in this example. - -Firstly - the ``MembershipInline`` class references ``Group.members.through``. -The ``through`` attribute is a reference to the model that manages the -many-to-many relation. This model is automatically created by Django when you -define a many-to-many field. - -Secondly, the ``GroupAdmin`` must manually exclude the ``members`` field. -Django displays an admin widget for a many-to-many field on the model that -defines the relation (in this case, ``Group``). If you want to use an inline -model to represent the many-to-many relationship, you must tell Django's admin -to *not* display this widget - otherwise you will end up with two widgets on -your admin page for managing the relation. - -In all other respects, the ``InlineModelAdmin`` is exactly the same as any -other. You can customize the appearance using any of the normal -``ModelAdmin`` properties. - -Working with Many-to-Many Intermediary Models ----------------------------------------------- - -When you specify an intermediary model using the ``through`` argument to a -``ManyToManyField``, the admin will not display a widget by default. This is -because each instance of that intermediary model requires more information -than could be displayed in a single widget, and the layout required for -multiple widgets will vary depending on the intermediate model. - -However, we still want to be able to edit that information inline. Fortunately, -this is easy to do with inline admin models. Suppose we have the following -models:: - - class Person(models.Model): - name = models.CharField(max_length=128) - - class Group(models.Model): - name = models.CharField(max_length=128) - members = models.ManyToManyField(Person, through='Membership') - - class Membership(models.Model): - person = models.ForeignKey(Person) - group = models.ForeignKey(Group) - date_joined = models.DateField() - invite_reason = models.CharField(max_length=64) - -The first step in displaying this intermediate model in the admin is to -define an inline class for the ``Membership`` model:: - - class MembershipInline(admin.TabularInline): - model = Membership - extra = 1 - -This simple example uses the default ``InlineModelAdmin`` values for the -``Membership`` model, and limits the extra add forms to one. This could be -customized using any of the options available to ``InlineModelAdmin`` classes. - -Now create admin views for the ``Person`` and ``Group`` models:: - - class PersonAdmin(admin.ModelAdmin): - inlines = (MembershipInline,) - - class GroupAdmin(admin.ModelAdmin): - inlines = (MembershipInline,) - -Finally, register your ``Person`` and ``Group`` models with the admin site:: - - admin.site.register(Person, PersonAdmin) - admin.site.register(Group, GroupAdmin) - -Now your admin site is set up to edit ``Membership`` objects inline from -either the ``Person`` or the ``Group`` detail pages. - -Using generic relations as an inline ------------------------------------- - -It is possible to use an inline with generically related objects. Let's say -you have the following models:: - - class Image(models.Model): - image = models.ImageField(upload_to="images") - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey("content_type", "object_id") - - class Product(models.Model): - name = models.CharField(max_length=100) - -If you want to allow editing and creating ``Image`` instance on the ``Product`` -add/change views you can simply use ``GenericInlineModelAdmin`` provided by -``django.contrib.contenttypes.generic``. In your ``admin.py`` for this -example app:: - - from django.contrib import admin - from django.contrib.contenttypes import generic - - from myproject.myapp.models import Image, Product - - class ImageInline(generic.GenericTabularInline): - model = Image - - class ProductAdmin(admin.ModelAdmin): - inlines = [ - ImageInline, - ] - - admin.site.register(Product, ProductAdmin) - -``django.contrib.contenttypes.generic`` provides both a ``GenericTabularInline`` -and ``GenericStackedInline`` and behave just like any other inline. See the -:doc:`contenttypes documentation </ref/contrib/contenttypes>` for more specific -information. - -Overriding Admin Templates -========================== - -It is relatively easy to override many of the templates which the admin module -uses to generate the various pages of an admin site. You can even override a few -of these templates for a specific app, or a specific model. - -Set up your projects admin template directories ------------------------------------------------ - -The admin template files are located in the ``contrib/admin/templates/admin`` -directory. - -In order to override one or more of them, first create an ``admin`` directory in -your project's ``templates`` directory. This can be any of the directories you -specified in ``TEMPLATE_DIRS``. - -Within this ``admin`` directory, create sub-directories named after your app. -Within these app subdirectories create sub-directories named after your models. -Note, that the admin app will lowercase the model name when looking for the -directory, so make sure you name the directory in all lowercase if you are going -to run your app on a case-sensitive filesystem. - -To override an admin template for a specific app, copy and edit the template -from the ``django/contrib/admin/templates/admin`` directory, and save it to one -of the directories you just created. - -For example, if we wanted to add a tool to the change list view for all the -models in an app named ``my_app``, we would copy -``contrib/admin/templates/admin/change_list.html`` to the -``templates/admin/my_app/`` directory of our project, and make any necessary -changes. - -If we wanted to add a tool to the change list view for only a specific model -named 'Page', we would copy that same file to the -``templates/admin/my_app/page`` directory of our project. - -Overriding vs. replacing an admin template ------------------------------------------- - -Because of the modular design of the admin templates, it is usually neither -necessary nor advisable to replace an entire template. It is almost always -better to override only the section of the template which you need to change. - -To continue the example above, we want to add a new link next to the ``History`` -tool for the ``Page`` model. After looking at ``change_form.html`` we determine -that we only need to override the ``object-tools`` block. Therefore here is our -new ``change_form.html`` : - -.. code-block:: html+django - - {% extends "admin/change_form.html" %} - {% load i18n %} - {% block object-tools %} - {% if change %}{% if not is_popup %} - <ul class="object-tools"> - <li><a href="history/" class="historylink">{% trans "History" %}</a></li> - <li><a href="mylink/" class="historylink">My Link</a></li> - {% if has_absolute_url %} - <li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink"> - {% trans "View on site" %}</a> - </li> - {% endif%} - </ul> - {% endif %}{% endif %} - {% endblock %} - -And that's it! If we placed this file in the ``templates/admin/my_app`` -directory, our link would appear on every model's change form. - -Templates which may be overridden per app or model --------------------------------------------------- - -Not every template in ``contrib/admin/templates/admin`` may be overridden per -app or per model. The following can: - - * ``app_index.html`` - * ``change_form.html`` - * ``change_list.html`` - * ``delete_confirmation.html`` - * ``object_history.html`` - -For those templates that cannot be overridden in this way, you may still -override them for your entire project. Just place the new version in your -``templates/admin`` directory. This is particularly useful to create custom 404 -and 500 pages. - -.. note:: - - Some of the admin templates, such as ``change_list_request.html`` are used - to render custom inclusion tags. These may be overridden, but in such cases - you are probably better off creating your own version of the tag in question - and giving it a different name. That way you can use it selectively. - -Root and login templates ------------------------- - -If you wish to change the index, login or logout templates, you are better off -creating your own ``AdminSite`` instance (see below), and changing the -:attr:`AdminSite.index_template` , :attr:`AdminSite.login_template` or -:attr:`AdminSite.logout_template` properties. - -``AdminSite`` objects -===================== - -.. class:: AdminSite(name=None) - -A Django administrative site is represented by an instance of -``django.contrib.admin.sites.AdminSite``; by default, an instance of -this class is created as ``django.contrib.admin.site`` and you can -register your models and ``ModelAdmin`` instances with it. - -If you'd like to set up your own administrative site with custom -behavior, however, you're free to subclass ``AdminSite`` and override -or add anything you like. Then, simply create an instance of your -``AdminSite`` subclass (the same way you'd instantiate any other -Python class), and register your models and ``ModelAdmin`` subclasses -with it instead of using the default. - -.. versionadded:: 1.1 - -When constructing an instance of an ``AdminSite``, you are able to provide -a unique instance name using the ``name`` argument to the constructor. This -instance name is used to identify the instance, especially when -:ref:`reversing admin URLs <admin-reverse-urls>`. If no instance name is -provided, a default instance name of ``admin`` will be used. - -``AdminSite`` attributes ------------------------- - -Templates can override or extend base admin templates as described in -`Overriding Admin Templates`_. - -.. attribute:: AdminSite.index_template - -Path to a custom template that will be used by the admin site main index view. - -.. attribute:: AdminSite.login_template - -Path to a custom template that will be used by the admin site login view. - -.. attribute:: AdminSite.logout_template - -.. versionadded:: 1.2 - -Path to a custom template that will be used by the admin site logout view. - -.. attribute:: AdminSite.password_change_template - -.. versionadded:: 1.2 - -Path to a custom template that will be used by the admin site password change -view. - -.. attribute:: AdminSite.password_change_done_template - -.. versionadded:: 1.2 - -Path to a custom template that will be used by the admin site password change -done view. - -Hooking ``AdminSite`` instances into your URLconf -------------------------------------------------- - -The last step in setting up the Django admin is to hook your ``AdminSite`` -instance into your URLconf. Do this by pointing a given URL at the -``AdminSite.urls`` method. - -In this example, we register the default ``AdminSite`` instance -``django.contrib.admin.site`` at the URL ``/admin/`` :: - - # urls.py - from django.conf.urls.defaults import * - from django.contrib import admin - - admin.autodiscover() - - urlpatterns = patterns('', - (r'^admin/', include(admin.site.urls)), - ) - -Above we used ``admin.autodiscover()`` to automatically load the -``INSTALLED_APPS`` admin.py modules. - -In this example, we register the ``AdminSite`` instance -``myproject.admin.admin_site`` at the URL ``/myadmin/`` :: - - # urls.py - from django.conf.urls.defaults import * - from myproject.admin import admin_site - - urlpatterns = patterns('', - (r'^myadmin/', include(admin_site.urls)), - ) - -There is really no need to use autodiscover when using your own ``AdminSite`` -instance since you will likely be importing all the per-app admin.py modules -in your ``myproject.admin`` module. - -Multiple admin sites in the same URLconf ----------------------------------------- - -It's easy to create multiple instances of the admin site on the same -Django-powered Web site. Just create multiple instances of ``AdminSite`` and -root each one at a different URL. - -.. versionchanged:: 1.1 - The method for hooking ``AdminSite`` instances into urls has changed in - Django 1.1. - -In this example, the URLs ``/basic-admin/`` and ``/advanced-admin/`` feature -separate versions of the admin site -- using the ``AdminSite`` instances -``myproject.admin.basic_site`` and ``myproject.admin.advanced_site``, -respectively:: - - # urls.py - from django.conf.urls.defaults import * - from myproject.admin import basic_site, advanced_site - - urlpatterns = patterns('', - (r'^basic-admin/', include(basic_site.urls)), - (r'^advanced-admin/', include(advanced_site.urls)), - ) - -``AdminSite`` instances take a single argument to their constructor, their -name, which can be anything you like. This argument becomes the prefix to the -URL names for the purposes of :ref:`reversing them<admin-reverse-urls>`. This -is only necessary if you are using more than one ``AdminSite``. - -Adding views to admin sites ---------------------------- - -.. versionadded:: 1.1 - -Just like :class:`ModelAdmin`, :class:`AdminSite` provides a -:meth:`~django.contrib.admin.ModelAdmin.get_urls()` method -that can be overridden to define additional views for the site. To add -a new view to your admin site, extend the base -:meth:`~django.contrib.admin.ModelAdmin.get_urls()` method to include -a pattern for your new view. - -.. note:: - Any view you render that uses the admin templates, or extends the base - admin template, should provide the ``current_app`` argument to - ``RequestContext`` or ``Context`` when rendering the template. It should - be set to either ``self.name`` if your view is on an ``AdminSite`` or - ``self.admin_site.name`` if your view is on a ``ModelAdmin``. - -.. _admin-reverse-urls: - -Reversing Admin URLs -==================== - -.. versionadded:: 1.1 - -When an :class:`AdminSite` is deployed, the views provided by that site are -accessible using Django's :ref:`URL reversing system <naming-url-patterns>`. - -The :class:`AdminSite` provides the following named URL patterns: - - ====================== ======================== ============= - Page URL name Parameters - ====================== ======================== ============= - Index ``index`` - Logout ``logout`` - Password change ``password_change`` - Password change done ``password_change_done`` - i18n javascript ``jsi18n`` - Application index page ``app_list`` ``app_label`` - ====================== ======================== ============= - -Each :class:`ModelAdmin` instance provides an additional set of named URLs: - - ====================== =============================================== ============= - Page URL name Parameters - ====================== =============================================== ============= - Changelist ``{{ app_label }}_{{ model_name }}_changelist`` - Add ``{{ app_label }}_{{ model_name }}_add`` - History ``{{ app_label }}_{{ model_name }}_history`` ``object_id`` - Delete ``{{ app_label }}_{{ model_name }}_delete`` ``object_id`` - Change ``{{ app_label }}_{{ model_name }}_change`` ``object_id`` - ====================== =============================================== ============= - -These named URLs are registered with the application namespace ``admin``, and -with an instance namespace corresponding to the name of the Site instance. - -So - if you wanted to get a reference to the Change view for a particular -``Choice`` object (from the polls application) in the default admin, you would -call:: - - >>> from django.core import urlresolvers - >>> c = Choice.objects.get(...) - >>> change_url = urlresolvers.reverse('admin:polls_choice_change', args=(c.id,)) - -This will find the first registered instance of the admin application (whatever the instance -name), and resolve to the view for changing ``poll.Choice`` instances in that instance. - -If you want to find a URL in a specific admin instance, provide the name of that instance -as a ``current_app`` hint to the reverse call. For example, if you specifically wanted -the admin view from the admin instance named ``custom``, you would need to call:: - - >>> change_url = urlresolvers.reverse('custom:polls_choice_change', args=(c.id,)) - -For more details, see the documentation on :ref:`reversing namespaced URLs -<topics-http-reversing-url-namespaces>`. |