1
0
mirror of https://github.com/django/django.git synced 2025-05-10 00:46:28 +00:00

Fixed #17461 -- Doc'd the presumed order of foreign keys on the intermediary model of a self-referential m2m.

Thanks Giannis Terzopoulos and Sarah Boyce for the reviews.
This commit is contained in:
Clifford Gama 2024-11-03 16:32:55 +02:00 committed by Sarah Boyce
parent 0f5dd0dff3
commit 9d93e35c20
2 changed files with 42 additions and 3 deletions

View File

@ -2041,6 +2041,42 @@ that control how the relationship functions.
prefer Django not to create a backwards relation, set ``related_name``
to ``'+'``.
.. admonition:: Foreign key order in intermediary models
When defining an asymmetric many-to-many relationship from a model to
itself using an intermediary model without defining
:attr:`through_fields`, the first foreign key in the intermediary model
will be treated as representing the source side of the
``ManyToManyField``, and the second as the target side. For example::
from django.db import models
class Manufacturer(models.Model):
name = models.CharField(max_length=255)
clients = models.ManyToManyField(
"self", symmetrical=False, related_name="suppliers", through="Supply"
)
class Supply(models.Model):
supplier = models.ForeignKey(
Manufacturer, models.CASCADE, related_name="supplies_given"
)
client = models.ForeignKey(
Manufacturer, models.CASCADE, related_name="supplies_received"
)
product = models.CharField(max_length=255)
Here, the ``Manufacturer`` model defines the many-to-many relationship
with ``clients`` in its role as a supplier. Therefore, the ``supplier``
foreign key (the source) must come before the ``client`` foreign key
(the target) in the intermediary ``Supply`` model.
Specifying :attr:`through_fields=("supplier", "client")
<.ManyToManyField.through_fields>` on the ``ManyToManyField`` makes the
order of foreign keys on the ``through`` model irrelevant.
If you don't specify an explicit ``through`` model, there is still an
implicit ``through`` model class you can use to directly access the table
created to hold the association. It has three fields to link the models, a

View File

@ -533,9 +533,12 @@ There are a few restrictions on the intermediate model:
* For a model which has a many-to-many relationship to itself through an
intermediary model, two foreign keys to the same model are permitted, but
they will be treated as the two (different) sides of the many-to-many
relationship. If there are *more* than two foreign keys though, you
must also specify ``through_fields`` as above, or a validation error
will be raised.
relationship. If :attr:`~.ManyToManyField.through_fields` is not specified,
the first foreign key will be taken to represent the source side of the
``ManyToManyField``, while the second will be taken to represent the target
side. If there are *more* than two foreign keys though, you must specify
:attr:`~.ManyToManyField.through_fields` to explicitly indicate which foreign
keys to use, otherwise a validation error will be raised.
Now that you have set up your :class:`~django.db.models.ManyToManyField` to use
your intermediary model (``Membership``, in this case), you're ready to start