summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/ref/models/fields.txt36
-rw-r--r--docs/topics/db/models.txt9
2 files changed, 42 insertions, 3 deletions
diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt
index 0456c0a064..faaa8babd8 100644
--- a/docs/ref/models/fields.txt
+++ b/docs/ref/models/fields.txt
@@ -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
diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt
index 98fb149b98..14233cbefd 100644
--- a/docs/topics/db/models.txt
+++ b/docs/topics/db/models.txt
@@ -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