mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	git-svn-id: http://code.djangoproject.com/svn/django/trunk@8111 bcc190cf-cafb-0310-a4f2-bffc1f526a37
		
			
				
	
	
		
			684 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			684 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| =====================
 | |
| The Django admin site
 | |
| =====================
 | |
| 
 | |
| One of the most powerful parts of Django is the automatic admin interface. It
 | |
| reads metadata in your model to provide a powerful and production-ready
 | |
| interface that content producers can immediately use to start adding content to
 | |
| the site. In this document, we discuss how to activate, use and customize
 | |
| Django's admin interface.
 | |
| 
 | |
| .. admonition:: Note
 | |
| 
 | |
|     The admin site has been refactored significantly since Django 0.96. This
 | |
|     document describes the newest version of the admin site, which allows for
 | |
|     much richer customization. If you follow the development of Django itself,
 | |
|     you may have heard this described as "newforms-admin."
 | |
| 
 | |
| Overview
 | |
| ========
 | |
| 
 | |
| There are five steps in activating the Django admin site:
 | |
| 
 | |
|     1. Add ``django.contrib.admin`` to your ``INSTALLED_APPS`` setting.
 | |
| 
 | |
|     2. Determine which of your application's models should be editable in the
 | |
|        admin interface.
 | |
| 
 | |
|     3. For each of those models, optionally create a ``ModelAdmin`` class that
 | |
|        encapsulates the customized admin functionality and options for that
 | |
|        particular model.
 | |
| 
 | |
|     4. Instantiate an ``AdminSite`` and tell it about each of your models and
 | |
|        ``ModelAdmin`` classes.
 | |
| 
 | |
|     5. Hook the ``AdminSite`` instance into your URLconf.
 | |
| 
 | |
| ``ModelAdmin`` objects
 | |
| ======================
 | |
| 
 | |
| The ``ModelAdmin`` class is the representation of a model in the admin
 | |
| interface. These are stored in a file named ``admin.py`` in your application.
 | |
| Let's take a look at a very simple example the ``ModelAdmin``::
 | |
| 
 | |
|     from django.contrib import admin
 | |
|     from myproject.myapp.models import Author
 | |
| 
 | |
|     class AuthorAdmin(admin.ModelAdmin):
 | |
|         pass
 | |
|     admin.site.register(Author, AuthorAdmin)
 | |
| 
 | |
| ``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'
 | |
| 
 | |
| ``date_hierarchy``
 | |
| ~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Set ``date_hierarchy`` to the name of a ``DateField`` or ``DateTimeField`` in
 | |
| your model, and the change list page will include a date-based drilldown
 | |
| navigation by that field.
 | |
| 
 | |
| Example::
 | |
| 
 | |
|     date_hierarchy = 'pub_date'
 | |
| 
 | |
| ``fieldsets``
 | |
| ~~~~~~~~~~~~~
 | |
| 
 | |
| Set ``fieldsets`` to control the layout of admin "add" and "change" pages.
 | |
| 
 | |
| ``fieldsets`` is a list of two-tuples, in which each two-tuple represents a
 | |
| ``<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:: http://media.djangoproject.com/img/doc/flatfiles_admin.png
 | |
| 
 | |
| If ``fieldsets`` isn't given, Django will default to displaying each field
 | |
| that isn't an ``AutoField`` and has ``editable=True``, in a single fieldset,
 | |
| in the same order as the fields are defined in the model.
 | |
| 
 | |
| The ``field_options`` dictionary can have the following keys:
 | |
| 
 | |
| ``fields``
 | |
|     A tuple of field names to display in this fieldset. This key is required.
 | |
| 
 | |
|     Example::
 | |
| 
 | |
|         {
 | |
|         'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
 | |
|         }
 | |
| 
 | |
|     To display multiple fields on the same line, wrap those fields in their own
 | |
|     tuple. In this example, the ``first_name`` and ``last_name`` fields will
 | |
|     display on the same line::
 | |
| 
 | |
|         {
 | |
|         'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
 | |
|         }
 | |
| 
 | |
| ``classes``
 | |
|     A 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.
 | |
| 
 | |
| ``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.
 | |
| 
 | |
| ``filter_vertical``
 | |
| ~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Same as ``filter_horizontal``, but is a vertical display of the filter
 | |
| interface.
 | |
| 
 | |
| ``list_display``
 | |
| ~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Set ``list_display`` to control which fields are displayed on the change list
 | |
| page of the admin.
 | |
| 
 | |
| Example::
 | |
| 
 | |
|     list_display = ('first_name', 'last_name')
 | |
| 
 | |
| If you don't set ``list_display``, the admin site will display a single column
 | |
| that displays the ``__unicode__()`` representation of each object.
 | |
| 
 | |
| A few special cases to note about ``list_display``:
 | |
| 
 | |
|     * If the field is a ``ForeignKey``, Django will display the
 | |
|       ``__unicode__()`` of the related object.
 | |
| 
 | |
|     * ``ManyToManyField`` fields aren't supported, because that would entail
 | |
|       executing a separate SQL statement for each row in the table. If you
 | |
|       want to do this nonetheless, give your model a custom method, and add
 | |
|       that method's name to ``list_display``. (See below for more on custom
 | |
|       methods in ``list_display``.)
 | |
| 
 | |
|     * If the field is a ``BooleanField`` or ``NullBooleanField``, Django will
 | |
|       display a pretty "on" or "off" icon instead of ``True`` or ``False``.
 | |
| 
 | |
|     * If the string given is a method of the model, Django will call it and
 | |
|       display the output. This method should have a ``short_description``
 | |
|       function attribute, for use as the header for the field.
 | |
| 
 | |
|       Here's a full example model::
 | |
| 
 | |
|           class Person(models.Model):
 | |
|               name = models.CharField(max_length=50)
 | |
|               birthday = models.DateField()
 | |
| 
 | |
|               def decade_born_in(self):
 | |
|                   return self.birthday.strftime('%Y')[:3] + "0's"
 | |
|               decade_born_in.short_description = 'Birth decade'
 | |
| 
 | |
|           class PersonAdmin(admin.ModelAdmin):
 | |
|               list_display = ('name', 'decade_born_in')
 | |
| 
 | |
|     * If the string given is a method of the model, Django will HTML-escape the
 | |
|       output by default. If you'd rather not escape the output of the method,
 | |
|       give the method an ``allow_tags`` attribute whose value is ``True``.
 | |
| 
 | |
|       Here's a full example model::
 | |
| 
 | |
|           class Person(models.Model):
 | |
|               first_name = models.CharField(max_length=50)
 | |
|               last_name = models.CharField(max_length=50)
 | |
|               color_code = models.CharField(max_length=6)
 | |
| 
 | |
|               def colored_name(self):
 | |
|                   return '<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 that returns True or False
 | |
|       Django will display a pretty "on" or "off" icon if you give the method a
 | |
|       ``boolean`` attribute whose value is ``True``.
 | |
| 
 | |
|       Here's a full example model::
 | |
| 
 | |
|           class Person(models.Model):
 | |
|               first_name = models.CharField(max_length=50)
 | |
|               birthday = models.DateField()
 | |
| 
 | |
|               def born_in_fifties(self):
 | |
|                   return self.birthday.strftime('%Y')[:3] == 5
 | |
|               born_in_fifties.boolean = True
 | |
| 
 | |
|           class PersonAdmin(admin.ModelAdmin):
 | |
|               list_display = ('name', 'born_in_fifties')
 | |
| 
 | |
| 
 | |
|     * The ``__str__()`` and ``__unicode__()`` methods are just as valid in
 | |
|       ``list_display`` as any other model method, so it's perfectly OK to do
 | |
|       this::
 | |
| 
 | |
|           list_display = ('__unicode__', 'some_other_field')
 | |
| 
 | |
|     * Usually, elements of ``list_display`` that aren't actual database fields
 | |
|       can't be used in sorting (because Django does all the sorting at the
 | |
|       database level).
 | |
| 
 | |
|       However, if an element of ``list_display`` represents a certain database
 | |
|       field, you can indicate this fact by setting the ``admin_order_field``
 | |
|       attribute of the item.
 | |
| 
 | |
|       For example::
 | |
| 
 | |
|         class Person(models.Model):
 | |
|             first_name = models.CharField(max_length=50)
 | |
|             color_code = models.CharField(max_length=6)
 | |
| 
 | |
|             def colored_first_name(self):
 | |
|                 return '<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.
 | |
| 
 | |
| ``list_display_links``
 | |
| ~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Set ``list_display_links`` to control which fields in ``list_display`` should
 | |
| be linked to the "change" page for an object.
 | |
| 
 | |
| By default, the change list page will link the first column -- the first field
 | |
| specified in ``list_display`` -- to the change page for each item. But
 | |
| ``list_display_links`` lets you change which columns are linked. Set
 | |
| ``list_display_links`` to a list or tuple of field names (in the same format as
 | |
| ``list_display``) to link.
 | |
| 
 | |
| ``list_display_links`` can specify one or many field names. As long as the
 | |
| field names appear in ``list_display``, Django doesn't care how many (or how
 | |
| few) fields are linked. The only requirement is: If you want to use
 | |
| ``list_display_links``, you must define ``list_display``.
 | |
| 
 | |
| In this example, the ``first_name`` and ``last_name`` fields will be linked on
 | |
| the change list page::
 | |
| 
 | |
|     class PersonAdmin(admin.ModelAdmin):
 | |
|         list_display = ('first_name', 'last_name', 'birthday')
 | |
|         list_display_links = ('first_name', 'last_name')
 | |
| 
 | |
| Finally, note that in order to use ``list_display_links``, you must define
 | |
| ``list_display``, too.
 | |
| 
 | |
| ``list_filter``
 | |
| ~~~~~~~~~~~~~~~
 | |
| 
 | |
| Set ``list_filter`` to activate filters in the right sidebar of the change list
 | |
| page of the admin. This should be a list of field names, and each specified
 | |
| field should be either a ``BooleanField``, ``CharField``, ``DateField``,
 | |
| ``DateTimeField``, ``IntegerField`` or ``ForeignKey``.
 | |
| 
 | |
| This example, taken from the ``django.contrib.auth.models.User`` model, shows
 | |
| how both ``list_display`` and ``list_filter`` work::
 | |
| 
 | |
|     class UserAdmin(admin.ModelAdmin):
 | |
|         list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
 | |
|         list_filter = ('is_staff', 'is_superuser')
 | |
| 
 | |
| The above code results in an admin change list page that looks like this:
 | |
| 
 | |
|     .. image:: http://media.djangoproject.com/img/doc/users_changelist.png
 | |
| 
 | |
| (This example also has ``search_fields`` defined. See below.)
 | |
| 
 | |
| ``list_per_page``
 | |
| ~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Set ``list_per_page`` to control how many items appear on each paginated admin
 | |
| change list page. By default, this is set to ``100``.
 | |
| 
 | |
| ``list_select_related``
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Set ``list_select_related`` to tell Django to use ``select_related()`` in
 | |
| retrieving the list of objects on the admin change list page. This can save you
 | |
| a bunch of database queries.
 | |
| 
 | |
| The value should be either ``True`` or ``False``. Default is ``False``.
 | |
| 
 | |
| Note that Django will use ``select_related()``, regardless of this setting,
 | |
| if one of the ``list_display`` fields is a ``ForeignKey``.
 | |
| 
 | |
| For more on ``select_related()``, see `the select_related() docs`_.
 | |
| 
 | |
| .. _the select_related() docs: ../db-api/#select-related
 | |
| 
 | |
| ``inlines``
 | |
| ~~~~~~~~~~~
 | |
| 
 | |
| See ``InlineModelAdmin`` objects below.
 | |
| 
 | |
| ``ordering``
 | |
| ~~~~~~~~~~~~
 | |
| 
 | |
| Set ``ordering`` to specify how objects on the admin change list page should be
 | |
| ordered. This should be a list or tuple in the same format as a model's
 | |
| ``ordering`` parameter.
 | |
| 
 | |
| If this isn't provided, the Django admin will use the model's default ordering.
 | |
| 
 | |
| ``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.
 | |
| 
 | |
| ``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.
 | |
| 
 | |
| ``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 the primary key.
 | |
| 
 | |
| ``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``.
 | |
| 
 | |
| ``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``.
 | |
| 
 | |
| ``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`` with
 | |
| the lookup API "follow" notation::
 | |
| 
 | |
|     search_fields = ['foreign_key__related_fieldname']
 | |
| 
 | |
| 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.
 | |
| 
 | |
| ``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 `regular media definitions on forms`_.
 | |
| 
 | |
| .. _regular media definitions on forms: ../forms/#media
 | |
| 
 | |
| ``InlineModelAdmin`` objects
 | |
| ============================
 | |
| 
 | |
| The admin interface has the ability to edit models on the same page as a
 | |
| parent model. These are called inlines. You can add them to a model by
 | |
| specifying them in a ``ModelAdmin.inlines`` attribute::
 | |
| 
 | |
|     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:
 | |
| 
 | |
| ``model``
 | |
| ~~~~~~~~~
 | |
| 
 | |
| The model in which the inline is using. This is required.
 | |
| 
 | |
| ``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.
 | |
| 
 | |
| ``formset``
 | |
| ~~~~~~~~~~~
 | |
| 
 | |
| This defaults to ``BaseInlineFormset``. Using your own formset can give you
 | |
| many possibilities of customization. Inlines are built around
 | |
| `model formsets`_.
 | |
| 
 | |
| .. _model formsets: ../modelforms/#model-formsets
 | |
| 
 | |
| ``form``
 | |
| ~~~~~~~~
 | |
| 
 | |
| The value for ``form`` is inherited from ``ModelAdmin``. This is what is
 | |
| passed through to ``formset_factory`` when creating the formset for this
 | |
| inline.
 | |
| 
 | |
| ``extra``
 | |
| ~~~~~~~~~
 | |
| 
 | |
| This controls the number of extra forms the formset will display in addition
 | |
| to the initial forms. See the `formsets documentation`_ for more information.
 | |
| 
 | |
| .. _formsets documentation: ../forms/#formsets
 | |
| 
 | |
| ``max_num``
 | |
| ~~~~~~~~~~~
 | |
| 
 | |
| This controls the maximum number of forms to show in the inline. This doesn't
 | |
| directly corrolate to the number of objects, but can if the value is small
 | |
| enough. See `max_num in formsets`_ for more information.
 | |
| 
 | |
| .. _max_num in formsets: ../modelforms/#limiting-the-number-of-objects-editable
 | |
| 
 | |
| ``template``
 | |
| ~~~~~~~~~~~~
 | |
| 
 | |
| The template used to render the inline on the page.
 | |
| 
 | |
| ``verbose_name``
 | |
| ~~~~~~~~~~~~~~~~
 | |
| 
 | |
| An override to the ``verbose_name`` found in the model's inner ``Meta`` class.
 | |
| 
 | |
| ``verbose_name_plural``
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| An override to the ``verbose_name_plural`` found in the model's inner ``Meta``
 | |
| class.
 | |
| 
 | |
| 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,
 | |
|         ]
 | |
| 
 | |
| ``AdminSite`` objects
 | |
| =====================
 | |
| 
 | |
| 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.root`` 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('',
 | |
|         ('^admin/(.*)', admin.site.root),
 | |
|     )
 | |
| 
 | |
| 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('',
 | |
|         ('^myadmin/(.*)', admin_site.root),
 | |
|     )
 | |
| 
 | |
| 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.
 | |
| 
 | |
| Note that the regular expression in the URLpattern *must* group everything in
 | |
| the URL that comes after the URL root -- hence the ``(.*)`` in these examples.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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('',
 | |
|         ('^basic-admin/(.*)', basic_site.root),
 | |
|         ('^advanced-admin/(.*)', advanced_site.root),
 | |
|     )
 |