From 1e1ab5876a51fb1e688c903710e175d2d367e510 Mon Sep 17 00:00:00 2001 From: Clifford Gama Date: Sun, 3 Nov 2024 16:32:55 +0200 Subject: [PATCH] Fixed #17461 -- Doc'd the presumed order of foreign keys on intermediary M2M model. --- docs/ref/models/fields.txt | 28 ++++++++++++++++++++++++++++ docs/topics/db/models.txt | 13 +++++++------ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index 07e86785d9..5b65c1e1ae 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -2018,6 +2018,34 @@ that control how the relationship functions. prefer Django not to create a backwards relation, set ``related_name`` to ``'+'``. + .. admonition:: Order of foreign keys to source models in intermediary models + + When defining an asymmetric many-to-many relationship from a model to + itself using an intermediary model, 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" + ) + + + class Supply(models.Model): + supplier = models.ForeignKey(Manufacturer, models.CASCADE) + client = models.ForeignKey(Manufacturer, models.CASCADE) + product = models.CharField(max_length=255) + + Here, the ``Manufacturer`` model in its role as a supplier defines + the many-to-many relationship with ``clients``, so the ``supplier`` + foreign key must come before the ``clients`` foreign key in the + intermediary ``Supply`` model. + 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. diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index f7f575eb3f..5414d92e78 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -518,12 +518,13 @@ There are a few restrictions on the intermediate model: to the foreign key to the target model (this would be ``Person`` in our example). -* 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. +* For a model that has a many-to-many relationship to itself through an + intermediary model, two foreign keys to the same model are allowed, but they + will be treated as the two different sides of the many-to-many relationship. + The first foreign key in the intermediary model will be taken to represent + the source side of the ``ManyToManyField``, while the second will be taken to + represent the target side. If more than two foreign keys are defined, you + must specify ``through_fields``, or a validation error will occur. 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