PageRenderTime 125ms CodeModel.GetById 106ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 1ms

/docs/ref/contrib/admin/index.txt

https://code.google.com/p/mango-py/
Plain Text | 1744 lines | 1239 code | 505 blank | 0 comment | 0 complexity | 5d7cde0b64cd21f805e1b80b6951bc46 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1=====================
   2The Django admin site
   3=====================
   4
   5.. module:: django.contrib.admin
   6   :synopsis: Django's admin site.
   7
   8One of the most powerful parts of Django is the automatic admin interface. It
   9reads metadata in your model to provide a powerful and production-ready
  10interface that content producers can immediately use to start adding content to
  11the site. In this document, we discuss how to activate, use and customize
  12Django's admin interface.
  13
  14Overview
  15========
  16
  17There are six steps in activating the Django admin site:
  18
  19    1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS`
  20       setting.
  21
  22    2. Admin has two dependencies - :mod:`django.contrib.auth` and
  23       :mod:`django.contrib.contenttypes`. If these applications are not
  24       in your :setting:`INSTALLED_APPS` list, add them.
  25
  26    3. Determine which of your application's models should be editable in the
  27       admin interface.
  28
  29    4. For each of those models, optionally create a ``ModelAdmin`` class that
  30       encapsulates the customized admin functionality and options for that
  31       particular model.
  32
  33    5. Instantiate an ``AdminSite`` and tell it about each of your models and
  34       ``ModelAdmin`` classes.
  35
  36    6. Hook the ``AdminSite`` instance into your URLconf.
  37
  38Other topics
  39------------
  40
  41.. toctree::
  42   :maxdepth: 1
  43
  44   actions
  45   admindocs
  46
  47.. seealso::
  48
  49    For information about serving the static files (images, JavaScript, and
  50    CSS) associated with the admin in production, see :ref:`serving-files`.
  51
  52``ModelAdmin`` objects
  53======================
  54
  55.. class:: ModelAdmin
  56
  57    The ``ModelAdmin`` class is the representation of a model in the admin
  58    interface. These are stored in a file named ``admin.py`` in your
  59    application. Let's take a look at a very simple example of
  60    the ``ModelAdmin``::
  61
  62        from django.contrib import admin
  63        from myproject.myapp.models import Author
  64
  65        class AuthorAdmin(admin.ModelAdmin):
  66            pass
  67        admin.site.register(Author, AuthorAdmin)
  68
  69    .. admonition:: Do you need a ``ModelAdmin`` object at all?
  70
  71        In the preceding example, the ``ModelAdmin`` class doesn't define any
  72        custom values (yet). As a result, the default admin interface will be
  73        provided. If you are happy with the default admin interface, you don't
  74        need to define a ``ModelAdmin`` object at all -- you can register the
  75        model class without providing a ``ModelAdmin`` description. The
  76        preceding example could be simplified to::
  77
  78            from django.contrib import admin
  79            from myproject.myapp.models import Author
  80
  81            admin.site.register(Author)
  82
  83``ModelAdmin`` options
  84----------------------
  85
  86The ``ModelAdmin`` is very flexible. It has several options for dealing with
  87customizing the interface. All options are defined on the ``ModelAdmin``
  88subclass::
  89
  90    class AuthorAdmin(admin.ModelAdmin):
  91        date_hierarchy = 'pub_date'
  92
  93.. attribute:: ModelAdmin.actions
  94
  95    A list of actions to make available on the change list page. See
  96    :doc:`/ref/contrib/admin/actions` for details.
  97
  98.. attribute:: ModelAdmin.actions_on_top
  99.. attribute:: ModelAdmin.actions_on_bottom
 100
 101    Controls where on the page the actions bar appears. By default, the admin
 102    changelist displays actions at the top of the page (``actions_on_top = True;
 103    actions_on_bottom = False``).
 104
 105.. attribute:: ModelAdmin.actions_selection_counter
 106
 107    .. versionadded:: 1.2
 108
 109    Controls whether a selection counter is display next to the action dropdown.
 110    By default, the admin changelist will display it
 111    (``actions_selection_counter = True``).
 112
 113.. attribute:: ModelAdmin.date_hierarchy
 114
 115    Set ``date_hierarchy`` to the name of a ``DateField`` or ``DateTimeField``
 116    in your model, and the change list page will include a date-based drilldown
 117    navigation by that field.
 118
 119    Example::
 120
 121        date_hierarchy = 'pub_date'
 122
 123    .. versionadded:: 1.3
 124
 125    This will intelligently populate itself based on available data,
 126    e.g. if all the dates are in one month, it'll show the day-level
 127    drill-down only.
 128
 129.. attribute:: ModelAdmin.exclude
 130
 131    This attribute, if given, should be a list of field names to exclude from
 132    the form.
 133
 134    For example, let's consider the following model::
 135
 136        class Author(models.Model):
 137            name = models.CharField(max_length=100)
 138            title = models.CharField(max_length=3)
 139            birth_date = models.DateField(blank=True, null=True)
 140
 141    If you want a form for the ``Author`` model that includes only the ``name``
 142    and ``title`` fields, you would specify ``fields`` or ``exclude`` like
 143    this::
 144
 145        class AuthorAdmin(admin.ModelAdmin):
 146            fields = ('name', 'title')
 147
 148        class AuthorAdmin(admin.ModelAdmin):
 149            exclude = ('birth_date',)
 150
 151    Since the Author model only has three fields, ``name``, ``title``, and
 152    ``birth_date``, the forms resulting from the above declarations will
 153    contain exactly the same fields.
 154
 155.. attribute:: ModelAdmin.fields
 156
 157    Use this option as an alternative to ``fieldsets`` if the layout does not
 158    matter and if you want to only show a subset of the available fields in the
 159    form. For example, you could define a simpler version of the admin form for
 160    the ``django.contrib.flatpages.FlatPage`` model as follows::
 161
 162        class FlatPageAdmin(admin.ModelAdmin):
 163            fields = ('url', 'title', 'content')
 164
 165    In the above example, only the fields 'url', 'title' and 'content' will be
 166    displayed, sequentially, in the form.
 167
 168    .. versionadded:: 1.2
 169
 170    ``fields`` can contain values defined in :attr:`ModelAdmin.readonly_fields`
 171    to be displayed as read-only.
 172
 173    .. admonition:: Note
 174
 175        This ``fields`` option should not be confused with the ``fields``
 176        dictionary key that is within the ``fieldsets`` option, as described in
 177        the previous section.
 178
 179.. attribute:: ModelAdmin.fieldsets
 180
 181    Set ``fieldsets`` to control the layout of admin "add" and "change" pages.
 182
 183    ``fieldsets`` is a list of two-tuples, in which each two-tuple represents a
 184    ``<fieldset>`` on the admin form page. (A ``<fieldset>`` is a "section" of
 185    the form.)
 186
 187    The two-tuples are in the format ``(name, field_options)``, where ``name``
 188    is a string representing the title of the fieldset and ``field_options`` is
 189    a dictionary of information about the fieldset, including a list of fields
 190    to be displayed in it.
 191
 192    A full example, taken from the :class:`django.contrib.flatpages.FlatPage`
 193    model::
 194
 195        class FlatPageAdmin(admin.ModelAdmin):
 196            fieldsets = (
 197                (None, {
 198                    'fields': ('url', 'title', 'content', 'sites')
 199                }),
 200                ('Advanced options', {
 201                    'classes': ('collapse',),
 202                    'fields': ('enable_comments', 'registration_required', 'template_name')
 203                }),
 204            )
 205
 206    This results in an admin page that looks like:
 207
 208        .. image:: _images/flatfiles_admin.png
 209
 210    If ``fieldsets`` isn't given, Django will default to displaying each field
 211    that isn't an ``AutoField`` and has ``editable=True``, in a single
 212    fieldset, in the same order as the fields are defined in the model.
 213
 214    The ``field_options`` dictionary can have the following keys:
 215
 216        * ``fields``
 217            A tuple of field names to display in this fieldset. This key is
 218            required.
 219
 220            Example::
 221
 222                {
 223                'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
 224                }
 225
 226            To display multiple fields on the same line, wrap those fields in
 227            their own tuple. In this example, the ``first_name`` and
 228            ``last_name`` fields will display on the same line::
 229
 230                {
 231                'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
 232                }
 233
 234            .. versionadded:: 1.2
 235
 236            ``fields`` can contain values defined in
 237            :attr:`~ModelAdmin.readonly_fields` to be displayed as read-only.
 238
 239        * ``classes``
 240            A list containing extra CSS classes to apply to the fieldset.
 241
 242            Example::
 243
 244                {
 245                'classes': ['wide', 'extrapretty'],
 246                }
 247
 248            Two useful classes defined by the default admin site stylesheet are
 249            ``collapse`` and ``wide``. Fieldsets with the ``collapse`` style
 250            will be initially collapsed in the admin and replaced with a small
 251            "click to expand" link. Fieldsets with the ``wide`` style will be
 252            given extra horizontal space.
 253
 254        * ``description``
 255            A string of optional extra text to be displayed at the top of each
 256            fieldset, under the heading of the fieldset.
 257
 258            Note that this value is *not* HTML-escaped when it's displayed in
 259            the admin interface. This lets you include HTML if you so desire.
 260            Alternatively you can use plain text and
 261            ``django.utils.html.escape()`` to escape any HTML special
 262            characters.
 263
 264.. attribute:: ModelAdmin.filter_horizontal
 265
 266    By default, a :class:`~django.db.models.ManyToManyField` is displayed in
 267    the admin site with a ``<select multiple>``. However, multiple-select boxes
 268    can be difficult to use when selecting many items. Adding a
 269    :class:`~django.db.models.ManyToManyField` to this list will instead use
 270    a nifty unobtrusive JavaScript "filter" interface that allows searching
 271    within the options. The unselected and selected options appear in two boxes
 272    side by side. See :attr:`~ModelAdmin.filter_vertical` to use a vertical
 273    interface.
 274
 275.. attribute:: ModelAdmin.filter_vertical
 276
 277    Same as :attr:`~ModelAdmin.filter_horizontal`, but uses a vertical display
 278    of the filter interface with the box of unselected options appearing above
 279    the box of selected options.
 280
 281.. attribute:: ModelAdmin.form
 282
 283    By default a ``ModelForm`` is dynamically created for your model. It is
 284    used to create the form presented on both the add/change pages. You can
 285    easily provide your own ``ModelForm`` to override any default form behavior
 286    on the add/change pages.
 287
 288    For an example see the section `Adding custom validation to the admin`_.
 289
 290.. attribute:: ModelAdmin.formfield_overrides
 291
 292    This provides a quick-and-dirty way to override some of the
 293    :class:`~django.forms.Field` options for use in the admin.
 294    ``formfield_overrides`` is a dictionary mapping a field class to a dict of
 295    arguments to pass to the field at construction time.
 296
 297    Since that's a bit abstract, let's look at a concrete example. The most
 298    common use of ``formfield_overrides`` is to add a custom widget for a
 299    certain type of field. So, imagine we've written a ``RichTextEditorWidget``
 300    that we'd like to use for large text fields instead of the default
 301    ``<textarea>``. Here's how we'd do that::
 302
 303        from django.db import models
 304        from django.contrib import admin
 305
 306        # Import our custom widget and our model from where they're defined
 307        from myapp.widgets import RichTextEditorWidget
 308        from myapp.models import MyModel
 309
 310        class MyModelAdmin(admin.ModelAdmin):
 311            formfield_overrides = {
 312                models.TextField: {'widget': RichTextEditorWidget},
 313            }
 314
 315    Note that the key in the dictionary is the actual field class, *not* a
 316    string. The value is another dictionary; these arguments will be passed to
 317    :meth:`~django.forms.Field.__init__`. See :doc:`/ref/forms/api` for
 318    details.
 319
 320    .. warning::
 321
 322        If you want to use a custom widget with a relation field (i.e.
 323        :class:`~django.db.models.ForeignKey` or
 324        :class:`~django.db.models.ManyToManyField`), make sure you haven't
 325        included that field's name in ``raw_id_fields`` or ``radio_fields``.
 326
 327        ``formfield_overrides`` won't let you change the widget on relation
 328        fields that have ``raw_id_fields`` or ``radio_fields`` set. That's
 329        because ``raw_id_fields`` and ``radio_fields`` imply custom widgets of
 330        their own.
 331
 332.. attribute:: ModelAdmin.inlines
 333
 334    See :class:`InlineModelAdmin` objects below.
 335
 336.. attribute:: ModelAdmin.list_display
 337
 338    Set ``list_display`` to control which fields are displayed on the change
 339    list page of the admin.
 340
 341    Example::
 342
 343        list_display = ('first_name', 'last_name')
 344
 345    If you don't set ``list_display``, the admin site will display a single
 346    column that displays the ``__unicode__()`` representation of each object.
 347
 348    You have four possible values that can be used in ``list_display``:
 349
 350        * A field of the model. For example::
 351
 352              class PersonAdmin(admin.ModelAdmin):
 353                  list_display = ('first_name', 'last_name')
 354
 355        * A callable that accepts one parameter for the model instance. For
 356          example::
 357
 358              def upper_case_name(obj):
 359                  return ("%s %s" % (obj.first_name, obj.last_name)).upper()
 360              upper_case_name.short_description = 'Name'
 361
 362              class PersonAdmin(admin.ModelAdmin):
 363                  list_display = (upper_case_name,)
 364
 365        * A string representing an attribute on the ``ModelAdmin``. This
 366          behaves same as the callable. For example::
 367
 368              class PersonAdmin(admin.ModelAdmin):
 369                  list_display = ('upper_case_name',)
 370
 371                  def upper_case_name(self, obj):
 372                    return ("%s %s" % (obj.first_name, obj.last_name)).upper()
 373                  upper_case_name.short_description = 'Name'
 374
 375        * A string representing an attribute on the model. This behaves almost
 376          the same as the callable, but ``self`` in this context is the model
 377          instance. Here's a full model example::
 378
 379              class Person(models.Model):
 380                  name = models.CharField(max_length=50)
 381                  birthday = models.DateField()
 382
 383                  def decade_born_in(self):
 384                      return self.birthday.strftime('%Y')[:3] + "0's"
 385                  decade_born_in.short_description = 'Birth decade'
 386
 387              class PersonAdmin(admin.ModelAdmin):
 388                  list_display = ('name', 'decade_born_in')
 389
 390    A few special cases to note about ``list_display``:
 391
 392        * If the field is a ``ForeignKey``, Django will display the
 393          ``__unicode__()`` of the related object.
 394
 395        * ``ManyToManyField`` fields aren't supported, because that would
 396          entail executing a separate SQL statement for each row in the table.
 397          If you want to do this nonetheless, give your model a custom method,
 398          and add that method's name to ``list_display``. (See below for more
 399          on custom methods in ``list_display``.)
 400
 401        * If the field is a ``BooleanField`` or ``NullBooleanField``, Django
 402          will display a pretty "on" or "off" icon instead of ``True`` or
 403          ``False``.
 404
 405        * If the string given is a method of the model, ``ModelAdmin`` or a
 406          callable, Django will HTML-escape the output by default. If you'd
 407          rather not escape the output of the method, give the method an
 408          ``allow_tags`` attribute whose value is ``True``.
 409
 410          Here's a full example model::
 411
 412              class Person(models.Model):
 413                  first_name = models.CharField(max_length=50)
 414                  last_name = models.CharField(max_length=50)
 415                  color_code = models.CharField(max_length=6)
 416
 417                  def colored_name(self):
 418                      return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name)
 419                  colored_name.allow_tags = True
 420
 421              class PersonAdmin(admin.ModelAdmin):
 422                  list_display = ('first_name', 'last_name', 'colored_name')
 423
 424        * If the string given is a method of the model, ``ModelAdmin`` or a
 425          callable that returns True or False Django will display a pretty
 426          "on" or "off" icon if you give the method a ``boolean`` attribute
 427          whose value is ``True``.
 428
 429          Here's a full example model::
 430
 431              class Person(models.Model):
 432                  first_name = models.CharField(max_length=50)
 433                  birthday = models.DateField()
 434
 435                  def born_in_fifties(self):
 436                      return self.birthday.strftime('%Y')[:3] == '195'
 437                  born_in_fifties.boolean = True
 438
 439              class PersonAdmin(admin.ModelAdmin):
 440                  list_display = ('name', 'born_in_fifties')
 441
 442
 443        * The ``__str__()`` and ``__unicode__()`` methods are just as valid in
 444          ``list_display`` as any other model method, so it's perfectly OK to
 445          do this::
 446
 447              list_display = ('__unicode__', 'some_other_field')
 448
 449        * Usually, elements of ``list_display`` that aren't actual database
 450          fields can't be used in sorting (because Django does all the sorting
 451          at the database level).
 452
 453          However, if an element of ``list_display`` represents a certain
 454          database field, you can indicate this fact by setting the
 455          ``admin_order_field`` attribute of the item.
 456
 457          For example::
 458
 459            class Person(models.Model):
 460                first_name = models.CharField(max_length=50)
 461                color_code = models.CharField(max_length=6)
 462
 463                def colored_first_name(self):
 464                    return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name)
 465                colored_first_name.allow_tags = True
 466                colored_first_name.admin_order_field = 'first_name'
 467
 468            class PersonAdmin(admin.ModelAdmin):
 469                list_display = ('first_name', 'colored_first_name')
 470
 471          The above will tell Django to order by the ``first_name`` field when
 472          trying to sort by ``colored_first_name`` in the admin.
 473
 474.. attribute:: ModelAdmin.list_display_links
 475
 476    Set ``list_display_links`` to control which fields in ``list_display``
 477    should be linked to the "change" page for an object.
 478
 479    By default, the change list page will link the first column -- the first
 480    field specified in ``list_display`` -- to the change page for each item.
 481    But ``list_display_links`` lets you change which columns are linked. Set
 482    ``list_display_links`` to a list or tuple of fields (in the same
 483    format as ``list_display``) to link.
 484
 485    ``list_display_links`` can specify one or many fields. As long as the
 486    fields appear in ``list_display``, Django doesn't care how many (or
 487    how few) fields are linked. The only requirement is: If you want to use
 488    ``list_display_links``, you must define ``list_display``.
 489
 490    In this example, the ``first_name`` and ``last_name`` fields will be
 491    linked on the change list page::
 492
 493        class PersonAdmin(admin.ModelAdmin):
 494            list_display = ('first_name', 'last_name', 'birthday')
 495            list_display_links = ('first_name', 'last_name')
 496
 497    .. _admin-list-editable:
 498
 499.. attribute:: ModelAdmin.list_editable
 500
 501    Set ``list_editable`` to a list of field names on the model which will
 502    allow editing on the change list page. That is, fields listed in
 503    ``list_editable`` will be displayed as form widgets on the change list
 504    page, allowing users to edit and save multiple rows at once.
 505
 506    .. note::
 507
 508        ``list_editable`` interacts with a couple of other options in
 509        particular ways; you should note the following rules:
 510
 511            * Any field in ``list_editable`` must also be in ``list_display``.
 512              You can't edit a field that's not displayed!
 513
 514            * The same field can't be listed in both ``list_editable`` and
 515              ``list_display_links`` -- a field can't be both a form and
 516              a link.
 517
 518        You'll get a validation error if either of these rules are broken.
 519
 520.. attribute:: ModelAdmin.list_filter
 521
 522    Set ``list_filter`` to activate filters in the right sidebar of the change
 523    list page of the admin. This should be a list of field names, and each
 524    specified field should be either a ``BooleanField``, ``CharField``,
 525    ``DateField``, ``DateTimeField``, ``IntegerField`` or ``ForeignKey``.
 526
 527    This example, taken from the ``django.contrib.auth.models.User`` model,
 528    shows how both ``list_display`` and ``list_filter`` work::
 529
 530        class UserAdmin(admin.ModelAdmin):
 531            list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
 532            list_filter = ('is_staff', 'is_superuser')
 533
 534    The above code results in an admin change list page that looks like this:
 535
 536        .. image:: _images/users_changelist.png
 537
 538    (This example also has ``search_fields`` defined. See below.)
 539
 540    .. versionadded:: 1.3
 541
 542    Fields in ``list_filter`` can also span relations using the ``__`` lookup::
 543
 544        class UserAdminWithLookup(UserAdmin):
 545            list_filter = ('groups__name')
 546
 547.. attribute:: ModelAdmin.list_per_page
 548
 549    Set ``list_per_page`` to control how many items appear on each paginated
 550    admin change list page. By default, this is set to ``100``.
 551
 552.. attribute:: ModelAdmin.list_select_related
 553
 554    Set ``list_select_related`` to tell Django to use
 555    :meth:`~django.db.models.QuerySet.select_related` in retrieving the list of
 556    objects on the admin change list page. This can save you a bunch of
 557    database queries.
 558
 559    The value should be either ``True`` or ``False``. Default is ``False``.
 560
 561    Note that Django will use :meth:`~django.db.models.QuerySet.select_related`,
 562    regardless of this setting if one of the ``list_display`` fields is a
 563    ``ForeignKey``.
 564
 565.. attribute:: ModelAdmin.ordering
 566
 567    Set ``ordering`` to specify how lists of objects should be ordered in the
 568    Django admin views. This should be a list or tuple in the same format as a
 569    model's :attr:`~django.db.models.Options.ordering` parameter.
 570
 571    If this isn't provided, the Django admin will use the model's default
 572    ordering.
 573
 574    .. admonition:: Note
 575
 576        Django will only honor the first element in the list/tuple; any others
 577        will be ignored.
 578
 579.. attribute:: ModelAdmin.paginator
 580
 581    .. versionadded:: 1.3
 582
 583    The paginator class to be used for pagination. By default,
 584    :class:`django.core.paginator.Paginator` is used. If the custom paginator
 585    class doesn't have the same constructor interface as
 586    :class:`django.core.paginator.Paginator`, you will also need to
 587    provide an implementation for :meth:`ModelAdmin.get_paginator`.
 588
 589.. attribute:: ModelAdmin.prepopulated_fields
 590
 591    Set ``prepopulated_fields`` to a dictionary mapping field names to the
 592    fields it should prepopulate from::
 593
 594        class ArticleAdmin(admin.ModelAdmin):
 595            prepopulated_fields = {"slug": ("title",)}
 596
 597    When set, the given fields will use a bit of JavaScript to populate from
 598    the fields assigned. The main use for this functionality is to
 599    automatically generate the value for ``SlugField`` fields from one or more
 600    other fields. The generated value is produced by concatenating the values
 601    of the source fields, and then by transforming that result into a valid
 602    slug (e.g. substituting dashes for spaces).
 603
 604    ``prepopulated_fields`` doesn't accept ``DateTimeField``, ``ForeignKey``,
 605    nor ``ManyToManyField`` fields.
 606
 607.. attribute:: ModelAdmin.radio_fields
 608
 609    By default, Django's admin uses a select-box interface (<select>) for
 610    fields that are ``ForeignKey`` or have ``choices`` set. If a field is
 611    present in ``radio_fields``, Django will use a radio-button interface
 612    instead. Assuming ``group`` is a ``ForeignKey`` on the ``Person`` model::
 613
 614        class PersonAdmin(admin.ModelAdmin):
 615            radio_fields = {"group": admin.VERTICAL}
 616
 617    You have the choice of using ``HORIZONTAL`` or ``VERTICAL`` from the
 618    ``django.contrib.admin`` module.
 619
 620    Don't include a field in ``radio_fields`` unless it's a ``ForeignKey`` or has
 621    ``choices`` set.
 622
 623.. attribute:: ModelAdmin.raw_id_fields
 624
 625    By default, Django's admin uses a select-box interface (<select>) for
 626    fields that are ``ForeignKey``. Sometimes you don't want to incur the
 627    overhead of having to select all the related instances to display in the
 628    drop-down.
 629
 630    ``raw_id_fields`` is a list of fields you would like to change
 631    into an ``Input`` widget for either a ``ForeignKey`` or
 632    ``ManyToManyField``::
 633
 634        class ArticleAdmin(admin.ModelAdmin):
 635            raw_id_fields = ("newspaper",)
 636
 637.. attribute:: ModelAdmin.readonly_fields
 638
 639    .. versionadded:: 1.2
 640
 641    By default the admin shows all fields as editable. Any fields in this
 642    option (which should be a ``list`` or ``tuple``) will display its data
 643    as-is and non-editable. This option behaves nearly identical to
 644    :attr:`ModelAdmin.list_display`. Usage is the same, however, when you
 645    specify :attr:`ModelAdmin.fields` or :attr:`ModelAdmin.fieldsets` the
 646    read-only fields must be present to be shown (they are ignored otherwise).
 647
 648    If ``readonly_fields`` is used without defining explicit ordering through
 649    :attr:`ModelAdmin.fields` or :attr:`ModelAdmin.fieldsets` they will be
 650    added last after all editable fields.
 651
 652.. attribute:: ModelAdmin.save_as
 653
 654    Set ``save_as`` to enable a "save as" feature on admin change forms.
 655
 656    Normally, objects have three save options: "Save", "Save and continue
 657    editing" and "Save and add another". If ``save_as`` is ``True``, "Save
 658    and add another" will be replaced by a "Save as" button.
 659
 660    "Save as" means the object will be saved as a new object (with a new ID),
 661    rather than the old object.
 662
 663    By default, ``save_as`` is set to ``False``.
 664
 665.. attribute:: ModelAdmin.save_on_top
 666
 667    Set ``save_on_top`` to add save buttons across the top of your admin change
 668    forms.
 669
 670    Normally, the save buttons appear only at the bottom of the forms. If you
 671    set ``save_on_top``, the buttons will appear both on the top and the
 672    bottom.
 673
 674    By default, ``save_on_top`` is set to ``False``.
 675
 676.. attribute:: ModelAdmin.search_fields
 677
 678    Set ``search_fields`` to enable a search box on the admin change list page.
 679    This should be set to a list of field names that will be searched whenever
 680    somebody submits a search query in that text box.
 681
 682    These fields should be some kind of text field, such as ``CharField`` or
 683    ``TextField``. You can also perform a related lookup on a ``ForeignKey`` or
 684    ``ManyToManyField`` with the lookup API "follow" notation::
 685
 686        search_fields = ['foreign_key__related_fieldname']
 687
 688    For example, if you have a blog entry with an author, the following
 689    definition would enable search blog entries by the email address of the
 690    author::
 691
 692        search_fields = ['user__email']
 693
 694    When somebody does a search in the admin search box, Django splits the
 695    search query into words and returns all objects that contain each of the
 696    words, case insensitive, where each word must be in at least one of
 697    ``search_fields``. For example, if ``search_fields`` is set to
 698    ``['first_name', 'last_name']`` and a user searches for ``john lennon``,
 699    Django will do the equivalent of this SQL ``WHERE`` clause::
 700
 701        WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
 702        AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
 703
 704    For faster and/or more restrictive searches, prefix the field name
 705    with an operator:
 706
 707    ``^``
 708        Matches the beginning of the field. For example, if ``search_fields``
 709        is set to ``['^first_name', '^last_name']`` and a user searches for
 710        ``john lennon``, Django will do the equivalent of this SQL ``WHERE``
 711        clause::
 712
 713            WHERE (first_name ILIKE 'john%' OR last_name ILIKE 'john%')
 714            AND (first_name ILIKE 'lennon%' OR last_name ILIKE 'lennon%')
 715
 716        This query is more efficient than the normal ``'%john%'`` query,
 717        because the database only needs to check the beginning of a column's
 718        data, rather than seeking through the entire column's data. Plus, if
 719        the column has an index on it, some databases may be able to use the
 720        index for this query, even though it's a ``LIKE`` query.
 721
 722    ``=``
 723        Matches exactly, case-insensitive. For example, if
 724        ``search_fields`` is set to ``['=first_name', '=last_name']`` and
 725        a user searches for ``john lennon``, Django will do the equivalent
 726        of this SQL ``WHERE`` clause::
 727
 728            WHERE (first_name ILIKE 'john' OR last_name ILIKE 'john')
 729            AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')
 730
 731        Note that the query input is split by spaces, so, following this
 732        example, it's currently not possible to search for all records in which
 733        ``first_name`` is exactly ``'john winston'`` (containing a space).
 734
 735    ``@``
 736        Performs a full-text match. This is like the default search method but
 737        uses an index. Currently this is only available for MySQL.
 738
 739Custom template options
 740~~~~~~~~~~~~~~~~~~~~~~~
 741
 742The `Overriding Admin Templates`_ section describes how to override or extend
 743the default admin templates.  Use the following options to override the default
 744templates used by the :class:`ModelAdmin` views:
 745
 746.. attribute:: ModelAdmin.add_form_template
 747
 748    .. versionadded:: 1.2
 749
 750    Path to a custom template, used by :meth:`add_view`.
 751
 752.. attribute:: ModelAdmin.change_form_template
 753
 754    Path to a custom template, used by :meth:`change_view`.
 755
 756.. attribute:: ModelAdmin.change_list_template
 757
 758    Path to a custom template, used by :meth:`changelist_view`.
 759
 760.. attribute:: ModelAdmin.delete_confirmation_template
 761
 762    Path to a custom template, used by :meth:`delete_view` for displaying a
 763    confirmation page when deleting one or more objects.
 764
 765.. attribute:: ModelAdmin.delete_selected_confirmation_template
 766
 767    .. versionadded:: 1.2
 768
 769    Path to a custom template, used by the :meth:`delete_selected`
 770    action method for displaying a confirmation page when deleting one
 771    or more objects. See the :doc:`actions
 772    documentation</ref/contrib/admin/actions>`.
 773
 774.. attribute:: ModelAdmin.object_history_template
 775
 776    Path to a custom template, used by :meth:`history_view`.
 777
 778
 779.. _model-admin-methods:
 780
 781``ModelAdmin`` methods
 782----------------------
 783
 784.. warning::
 785
 786    :meth:`ModelAdmin.save_model` and :meth:`ModelAdmin.delete_model` must
 787    save/delete the object, they are not for veto purposes, rather they allow
 788    you to perform extra operations.
 789
 790.. method:: ModelAdmin.save_model(self, request, obj, form, change)
 791
 792    The ``save_model`` method is given the ``HttpRequest``, a model instance,
 793    a ``ModelForm`` instance and a boolean value based on whether it is adding
 794    or changing the object. Here you can do any pre- or post-save operations.
 795
 796    For example to attach ``request.user`` to the object prior to saving::
 797
 798        class ArticleAdmin(admin.ModelAdmin):
 799            def save_model(self, request, obj, form, change):
 800                obj.user = request.user
 801                obj.save()
 802
 803.. method:: ModelAdmin.delete_model(self, request, obj)
 804
 805    .. versionadded:: 1.3
 806
 807    The ``delete_model`` method is given the ``HttpRequest`` and a model
 808    instance. Use this method to do pre- or post-delete operations.
 809
 810.. method:: ModelAdmin.save_formset(self, request, form, formset, change)
 811
 812    The ``save_formset`` method is given the ``HttpRequest``, the parent
 813    ``ModelForm`` instance and a boolean value based on whether it is adding or
 814    changing the parent object.
 815
 816    For example to attach ``request.user`` to each changed formset
 817    model instance::
 818
 819        class ArticleAdmin(admin.ModelAdmin):
 820            def save_formset(self, request, form, formset, change):
 821                instances = formset.save(commit=False)
 822                for instance in instances:
 823                    instance.user = request.user
 824                    instance.save()
 825                formset.save_m2m()
 826
 827.. method:: ModelAdmin.get_readonly_fields(self, request, obj=None)
 828
 829    .. versionadded:: 1.2
 830
 831    The ``get_readonly_fields`` method is given the ``HttpRequest`` and the
 832    ``obj`` being edited (or ``None`` on an add form) and is expected to return
 833    a ``list`` or ``tuple`` of field names that will be displayed as read-only,
 834    as described above in the :attr:`ModelAdmin.readonly_fields` section.
 835
 836.. method:: ModelAdmin.get_urls(self)
 837
 838    The ``get_urls`` method on a ``ModelAdmin`` returns the URLs to be used for
 839    that ModelAdmin in the same way as a URLconf.  Therefore you can extend
 840    them as documented in :doc:`/topics/http/urls`::
 841
 842        class MyModelAdmin(admin.ModelAdmin):
 843            def get_urls(self):
 844                urls = super(MyModelAdmin, self).get_urls()
 845                my_urls = patterns('',
 846                    (r'^my_view/$', self.my_view)
 847                )
 848                return my_urls + urls
 849
 850            def my_view(self, request):
 851                # custom view which should return an HttpResponse
 852                pass
 853
 854    .. note::
 855
 856        Notice that the custom patterns are included *before* the regular admin
 857        URLs: the admin URL patterns are very permissive and will match nearly
 858        anything, so you'll usually want to prepend your custom URLs to the
 859        built-in ones.
 860
 861        In this example, ``my_view`` will be accessed at
 862        ``/admin/myapp/mymodel/my_view/`` (assuming the admin URLs are included
 863        at ``/admin/``.)
 864
 865    However, the ``self.my_view`` function registered above suffers from two
 866    problems:
 867
 868      * It will *not* perform any permission checks, so it will be accessible
 869        to the general public.
 870      * It will *not* provide any header details to prevent caching. This means
 871        if the page retrieves data from the database, and caching middleware is
 872        active, the page could show outdated information.
 873
 874    Since this is usually not what you want, Django provides a convenience
 875    wrapper to check permissions and mark the view as non-cacheable. This
 876    wrapper is :meth:`AdminSite.admin_view` (i.e.
 877    ``self.admin_site.admin_view`` inside a ``ModelAdmin`` instance); use it
 878    like so::
 879
 880        class MyModelAdmin(admin.ModelAdmin):
 881            def get_urls(self):
 882                urls = super(MyModelAdmin, self).get_urls()
 883                my_urls = patterns('',
 884                    (r'^my_view/$', self.admin_site.admin_view(self.my_view))
 885                )
 886                return my_urls + urls
 887
 888    Notice the wrapped view in the fifth line above::
 889
 890        (r'^my_view/$', self.admin_site.admin_view(self.my_view))
 891
 892    This wrapping will protect ``self.my_view`` from unauthorized access and
 893    will apply the ``django.views.decorators.cache.never_cache`` decorator to
 894    make sure it is not cached if the cache middleware is active.
 895
 896    If the page is cacheable, but you still want the permission check to be
 897    performed, you can pass a ``cacheable=True`` argument to
 898    :meth:`AdminSite.admin_view`::
 899
 900        (r'^my_view/$', self.admin_site.admin_view(self.my_view, cacheable=True))
 901
 902.. method:: ModelAdmin.formfield_for_foreignkey(self, db_field, request, **kwargs)
 903
 904    The ``formfield_for_foreignkey`` method on a ``ModelAdmin`` allows you to
 905    override the default formfield for a foreign key field. For example, to
 906    return a subset of objects for this foreign key field based on the user::
 907
 908        class MyModelAdmin(admin.ModelAdmin):
 909            def formfield_for_foreignkey(self, db_field, request, **kwargs):
 910                if db_field.name == "car":
 911                    kwargs["queryset"] = Car.objects.filter(owner=request.user)
 912                return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
 913
 914    This uses the ``HttpRequest`` instance to filter the ``Car`` foreign key
 915    field to only display the cars owned by the ``User`` instance.
 916
 917.. method:: ModelAdmin.formfield_for_manytomany(self, db_field, request, **kwargs)
 918
 919    Like the ``formfield_for_foreignkey`` method, the
 920    ``formfield_for_manytomany`` method can be overridden to change the
 921    default formfield for a many to many field. For example, if an owner can
 922    own multiple cars and cars can belong to multiple owners -- a many to
 923    many relationship -- you could filter the ``Car`` foreign key field to
 924    only display the cars owned by the ``User``::
 925
 926        class MyModelAdmin(admin.ModelAdmin):
 927            def formfield_for_manytomany(self, db_field, request, **kwargs):
 928                if db_field.name == "cars":
 929                    kwargs["queryset"] = Car.objects.filter(owner=request.user)
 930                return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
 931
 932.. method:: ModelAdmin.formfield_for_choice_field(self, db_field, request, **kwargs)
 933
 934    Like the ``formfield_for_foreignkey`` and ``formfield_for_manytomany``
 935    methods, the ``formfield_for_choice_field`` method can be overridden to
 936    change the default formfield for a field that has declared choices. For
 937    example, if the choices available to a superuser should be different than
 938    those available to regular staff, you could proceed as follows::
 939
 940        class MyModelAdmin(admin.ModelAdmin):
 941            def formfield_for_choice_field(self, db_field, request, **kwargs):
 942                if db_field.name == "status":
 943                    kwargs['choices'] = (
 944                        ('accepted', 'Accepted'),
 945                        ('denied', 'Denied'),
 946                    )
 947                    if request.user.is_superuser:
 948                        kwargs['choices'] += (('ready', 'Ready for deployment'),)
 949                return super(MyModelAdmin, self).formfield_for_choice_field(db_field, request, **kwargs)
 950
 951.. method:: ModelAdmin.has_add_permission(self, request)
 952
 953    Should return ``True`` if adding an object is permitted, ``False``
 954    otherwise.
 955
 956.. method:: ModelAdmin.has_change_permission(self, request, obj=None)
 957
 958    Should return ``True`` if editing obj is permitted, ``False`` otherwise.
 959    If obj is ``None``, should return ``True`` or ``False`` to indicate whether
 960    editing of objects of this type is permitted in general (e.g., ``False``
 961    will be interpreted as meaning that the current user is not permitted to
 962    edit any object of this type).
 963
 964.. method:: ModelAdmin.has_delete_permission(self, request, obj=None)
 965
 966    Should return ``True`` if deleting obj is permitted, ``False`` otherwise.
 967    If obj is ``None``, should return ``True`` or ``False`` to indicate whether
 968    deleting objects of this type is permitted in general (e.g., ``False`` will
 969    be interpreted as meaning that the current user is not permitted to delete
 970    any object of this type).
 971
 972.. method:: ModelAdmin.queryset(self, request)
 973
 974    The ``queryset`` method on a ``ModelAdmin`` returns a
 975    :class:`~django.db.models.QuerySet` of all model instances that can be
 976    edited by the admin site. One use case for overriding this method is
 977    to show objects owned by the logged-in user::
 978
 979        class MyModelAdmin(admin.ModelAdmin):
 980            def queryset(self, request):
 981                qs = super(MyModelAdmin, self).queryset(request)
 982                if request.user.is_superuser:
 983                    return qs
 984                return qs.filter(author=request.user)
 985
 986.. method:: ModelAdmin.message_user(request, message)
 987
 988    Sends a message to the user. The default implementation creates a message
 989    using the :mod:`django.contrib.messages` backend. See the
 990    :ref:`custom ModelAdmin example <custom-admin-action>`.
 991
 992.. method:: ModelAdmin.get_paginator(queryset, per_page, orphans=0, allow_empty_first_page=True)
 993
 994    .. versionadded:: 1.3
 995
 996    Returns an instance of the paginator to use for this view. By default,
 997    instantiates an instance of :attr:`paginator`.
 998
 999Other methods
1000~~~~~~~~~~~~~
1001
1002.. method:: ModelAdmin.add_view(self, request, form_url='', extra_context=None)
1003
1004    Django view for the model instance addition page. See note below.
1005
1006.. method:: ModelAdmin.change_view(self, request, object_id, extra_context=None)
1007
1008    Django view for the model instance edition page. See note below.
1009
1010.. method:: ModelAdmin.changelist_view(self, request, extra_context=None)
1011
1012    Django view for the model instances change list/actions page. See note
1013    below.
1014
1015.. method:: ModelAdmin.delete_view(self, request, object_id, extra_context=None)
1016
1017    Django view for the model instance(s) deletion confirmation page. See note
1018    below.
1019
1020.. method:: ModelAdmin.history_view(self, request, object_id, extra_context=None)
1021
1022    Django view for the page that shows the modification history for a given
1023    model instance.
1024
1025Unlike the hook-type ``ModelAdmin`` methods detailed in the previous section,
1026these five methods are in reality designed to be invoked as Django views from
1027the admin application URL dispatching handler to render the pages that deal
1028with model instances CRUD operations. As a result, completely overriding these
1029methods will significantly change the behavior of the admin application.
1030
1031One common reason for overriding these methods is to augment the context data
1032that is provided to the template that renders the view. In the following
1033example, the change view is overridden so that the rendered template is
1034provided some extra mapping data that would not otherwise be available::
1035
1036    class MyModelAdmin(admin.ModelAdmin):
1037
1038        # A template for a very customized change view:
1039        change_form_template = 'admin/myapp/extras/openstreetmap_change_form.html'
1040
1041        def get_osm_info(self):
1042            # ...
1043            pass
1044
1045        def change_view(self, request, object_id, extra_context=None):
1046            my_context = {
1047                'osm_data': self.get_osm_info(),
1048            }
1049            return super(MyModelAdmin, self).change_view(request, object_id,
1050                extra_context=my_context)
1051
1052``ModelAdmin`` media definitions
1053--------------------------------
1054
1055There are times where you would like add a bit of CSS and/or JavaScript to
1056the add/change views. This can be accomplished by using a Media inner class
1057on your ``ModelAdmin``::
1058
1059    class ArticleAdmin(admin.ModelAdmin):
1060        class Media:
1061            css = {
1062                "all": ("my_styles.css",)
1063            }
1064            js = ("my_code.js",)
1065
1066.. versionchanged:: 1.3
1067
1068The :doc:`staticfiles app </ref/contrib/staticfiles>` prepends
1069:setting:`STATIC_URL` (or :setting:`MEDIA_URL` if :setting:`STATIC_URL` is
1070``None``) to any media paths. The same rules apply as :ref:`regular media
1071definitions on forms <form-media-paths>`.
1072
1073Django admin Javascript makes use of the `jQuery`_ library. To avoid
1074conflict with user scripts, Django's jQuery is namespaced as
1075``django.jQuery``. If you want to use jQuery in your own admin
1076JavaScript without including a second copy, you can use the
1077``django.jQuery`` object on changelist and add/edit views.
1078
1079.. _jQuery: http://jquery.com
1080
1081Adding custom validation to the admin
1082-------------------------------------
1083
1084Adding custom validation of data in the admin is quite easy. The automatic
1085admin interface reuses :mod:`django.forms`, and the ``ModelAdmin`` class gives
1086you the ability define your own form::
1087
1088    class ArticleAdmin(admin.ModelAdmin):
1089        form = MyArticleAdminForm
1090
1091``MyArticleAdminForm`` can be defined anywhere as long as you import where
1092needed. Now within your form you can add your own custom validation for
1093any field::
1094
1095    class MyArticleAdminForm(forms.ModelForm):
1096        class Meta:
1097            model = Article
1098
1099        def clean_name(self):
1100            # do something that validates your data
1101            return self.cleaned_data["name"]
1102
1103It is important you use a ``ModelForm`` here otherwise things can break. See
1104the :doc:`forms </ref/forms/index>` documentation on :doc:`custom validation
1105</ref/forms/validation>` and, more specifically, the
1106:ref:`model form validation notes <overriding-modelform-clean-method>` for more
1107information.
1108
1109.. _admin-inlines:
1110
1111``InlineModelAdmin`` objects
1112============================
1113
1114.. class:: InlineModelAdmin
1115.. class:: TabularInline
1116.. class:: StackedInline
1117
1118    The admin interface has the ability to edit models on the same page as a
1119    parent model. These are called inlines. Suppose you have these two models::
1120
1121         class Author(models.Model):
1122            name = models.CharField(max_length=100)
1123
1124         class Book(models.Model):
1125            author = models.ForeignKey(Author)
1126            title = models.CharField(max_length=100)
1127
1128    You can edit the books authored by an author on the author page. You add
1129    inlines to a model by specifying them in a ``ModelAdmin.inlines``::
1130
1131        class BookInline(admin.TabularInline):
1132            model = Book
1133
1134        class AuthorAdmin(admin.ModelAdmin):
1135            inlines = [
1136                BookInline,
1137            ]
1138
1139    Django provides two subclasses of ``InlineModelAdmin`` and they are:
1140
1141        * :class:`~django.contrib.admin.TabularInline`
1142        * :class:`~django.contrib.admin.StackedInline`
1143
1144    The difference between these two is merely the template used to render
1145    them.
1146
1147``InlineModelAdmin`` options
1148-----------------------------
1149
1150``InlineModelAdmin`` shares many of the same features as ``ModelAdmin``, and
1151adds some of its own (the shared features are actually defined in the
1152``BaseModelAdmin`` superclass). The shared features are:
1153
1154- :attr:`~InlineModelAdmin.form`
1155- :attr:`~ModelAdmin.fieldsets`
1156- :attr:`~ModelAdmin.fields`
1157- :attr:`~ModelAdmin.exclude`
1158- :attr:`~ModelAdmin.filter_horizontal`
1159- :attr:`~ModelAdmin.filter_vertical`
1160- :attr:`~ModelAdmin.prepopulated_fields`
1161- :attr:`~ModelAdmin.radio_fields`
1162- :attr:`~InlineModelAdmin.raw_id_fields`
1163- :meth:`~ModelAdmin.formfield_for_foreignkey`
1164- :meth:`~ModelAdmin.formfield_for_manytomany`
1165
1166.. versionadded:: 1.2
1167
1168- :attr:`~ModelAdmin.readonly_fields`
1169- :attr:`~ModelAdmin.formfield_overrides`
1170
1171.. versionadded:: 1.3
1172
1173- :attr:`~ModelAdmin.ordering`
1174- :meth:`~ModelAdmin.queryset`
1175
1176The ``InlineModelAdmin`` class adds:
1177
1178.. attribute:: InlineModelAdmin.model
1179
1180    The model in which the inline is using. This is required.
1181
1182.. attribute:: InlineModelAdmin.fk_name
1183
1184    The name of the foreign key on the model. In most cases this will be dealt
1185    with automatically, but ``fk_name`` must be specified explicitly if there
1186    are more than one foreign key to the same parent model.
1187
1188.. attribute:: InlineModelAdmin.formset
1189
1190    This defaults to ``BaseInlineFormSet``. Using your own formset can give you
1191    many possibilities of customization. Inlines are built around
1192    :ref:`model formsets <model-formsets>`.
1193
1194.. attribute:: InlineModelAdmin.form
1195
1196    The value for ``form`` defaults to ``ModelForm``. This is what is passed
1197    through to ``inlineformset_factory`` when creating the formset for this
1198    inline.
1199
1200    .. _ref-contrib-admin-inline-extra:
1201
1202.. attribute:: InlineModelAdmin.extra
1203
1204    This controls the number of extra forms the formset will display in
1205    addition to the initial forms. See the
1206    :doc:`formsets documentation </topics/forms/formsets>` for more
1207    information.
1208
1209    .. versionadded:: 1.2
1210
1211    For users with JavaScript-enabled browsers, an "Add another" link is
1212    provided to enable any number of additional inlines to be added in addition
1213    to those provided as a result of the ``extra`` argument.
1214
1215    The dynamic link will not appear if the number of currently displayed forms
1216    exceeds ``max_num``, or if the user does not have JavaScript enabled.
1217
1218    .. _ref-contrib-admin-inline-max-num:
1219
1220.. attribute:: InlineModelAdmin.max_num
1221
1222    This controls the maximum number of forms to show in the inline. This
1223    doesn't directly correlate to the number of objects, but can if the value
1224    is small enough. See :ref:`model-formsets-max-num` for more information.
1225
1226.. attribute:: InlineModelAdmin.raw_id_fields
1227
1228    By default, Django's admin uses a select-box interface (<select>) for
1229    fields that are ``ForeignKey``. Sometimes you don't want to incur the
1230    overhead of having to select all the related instances to display in the
1231    drop-down.
1232
1233    ``raw_id_fields`` is a list of fields you would like to change into a
1234    ``Input`` widget for either a ``ForeignKey`` or ``ManyToManyField``::
1235
1236        class BookInline(admin.TabularInline):
1237            model = Book
1238            raw_id_fields = ("pages",)
1239
1240
1241.. attribute:: InlineModelAdmin.template
1242
1243    The template used to render the inline on the page.
1244
1245.. attribute:: InlineModelAdmin.verbose_name
1246
1247    An override to the ``verbose_name`` found in the model's inner ``Meta``
1248    class.
1249
1250.. attribute:: InlineModelAdmin.verbose_name_plural
1251
1252    An override to the ``verbose_name_plural`` found in the model's inner
1253    ``Meta`` class.
1254
1255.. attribute:: InlineModelAdmin.can_delete
1256
1257    Specifies whether or not inline objects can be deleted in the inline.
1258    Defaults to ``True``.
1259
1260
1261Working with a model with two or more foreign keys to the same parent model
1262---------------------------------------------------------------------------
1263
1264It is sometimes possible to have more than one foreign key to the same model.
1265Take this model for instance::
1266
1267    class Friendship(models.Model):
1268        to_person = models.ForeignKey(Person, related_name="friends")
1269        from_person = models.ForeignKey(Person, related_name="from_friends")
1270
1271If you wanted to display an inline on the ``Person`` admin add/change pages
1272you need to explicitly define the foreign key since it is unable to do so
1273automatically::
1274
1275    class FriendshipInline(admin.TabularInline):
1276        model = Friendship
1277        fk_name = "to_person"
1278
1279    class PersonAdmin(admin.ModelAdmin):
1280        inlines = [
1281            FriendshipInline,
1282        ]
1283
1284Working with many-to-many models
1285

Large files files are truncated, but you can click here to view the full file