diff options
| author | Clifford Gama <cliffygamy@gmail.com> | 2024-11-03 16:32:55 +0200 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-05-02 09:02:16 +0200 |
| commit | 3c887e5e50ddcb84adef269e9558e603ca0ff620 (patch) | |
| tree | 0d557c95f8640459121aed4d6d017ac48cce74bc /docs/ref | |
| parent | 57c245199a0ea76e8155828a38c84192f39f18f4 (diff) | |
[5.2.x] 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.
Backport of 9d93e35c207a001de1aa9ca9165bdec824da9021 from main.
Diffstat (limited to 'docs/ref')
| -rw-r--r-- | docs/ref/models/fields.txt | 36 |
1 files changed, 36 insertions, 0 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 |
