Fixed #11795 -- Document (and slightly simplify) the use of inlines for m2m relations.
This is the first immediate benefit of m2m relations having an autogenerated model. git-svn-id: http://code.djangoproject.com/svn/django/trunk@11712 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
53b2c3867b
commit
dab3e97c1a
|
@ -586,6 +586,9 @@ class ReverseManyRelatedObjectsDescriptor(object):
|
|||
# ReverseManyRelatedObjectsDescriptor instance.
|
||||
def __init__(self, m2m_field):
|
||||
self.field = m2m_field
|
||||
# through is provided so that you have easy access to the through
|
||||
# model (Book.authors.through) for inlines, etc.
|
||||
self.through = m2m_field.rel.through
|
||||
|
||||
def __get__(self, instance, instance_type=None):
|
||||
if instance is None:
|
||||
|
|
|
@ -1048,16 +1048,68 @@ automatically::
|
|||
FriendshipInline,
|
||||
]
|
||||
|
||||
Working with Many-to-Many Models
|
||||
--------------------------------
|
||||
|
||||
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
|
||||
``InlineModelAdmin`` properties.
|
||||
|
||||
Working with Many-to-Many Intermediary Models
|
||||
----------------------------------------------
|
||||
|
||||
By default, admin widgets for many-to-many relations will be displayed inline
|
||||
on whichever model contains the actual reference to the ``ManyToManyField``.
|
||||
However, 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.
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue