Skip to content

Commit cc405e1

Browse files
cliff688sarahboyce
authored andcommitted
[5.1.x] Fixed #36128 -- Clarified auto-generated unique constraint on m2m through models.
Backport of ae2736c from main.
1 parent 03ace75 commit cc405e1

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

docs/ref/contrib/admin/index.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2635,6 +2635,13 @@ we can do this with inline admin models. Suppose we have the following models::
26352635
date_joined = models.DateField()
26362636
invite_reason = models.CharField(max_length=64)
26372637

2638+
class Meta:
2639+
constraints = [
2640+
models.UniqueConstraint(
2641+
fields=["person", "group"], name="unique_person_group"
2642+
)
2643+
]
2644+
26382645
The first step in displaying this intermediate model in the admin is to
26392646
define an inline class for the ``Membership`` model::
26402647

docs/ref/models/fields.txt

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,13 +2009,6 @@ that control how the relationship functions.
20092009
:ref:`extra data with a many-to-many relationship
20102010
<intermediary-manytomany>`.
20112011

2012-
.. note::
2013-
2014-
If you don't want multiple associations between the same instances, add
2015-
a :class:`~django.db.models.UniqueConstraint` including the from and to
2016-
fields. Django's automatically generated many-to-many tables include
2017-
such a constraint.
2018-
20192012
.. note::
20202013

20212014
Recursive relationships using an intermediary model can't determine the
@@ -2026,7 +2019,9 @@ that control how the relationship functions.
20262019

20272020
If you don't specify an explicit ``through`` model, there is still an
20282021
implicit ``through`` model class you can use to directly access the table
2029-
created to hold the association. It has three fields to link the models.
2022+
created to hold the association. It has three fields to link the models, a
2023+
primary key and two foreign keys. There is a unique constraint on the two
2024+
foreign keys.
20302025

20312026
If the source and target models differ, the following fields are
20322027
generated:

docs/topics/db/models.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,10 +507,22 @@ something like this::
507507
date_joined = models.DateField()
508508
invite_reason = models.CharField(max_length=64)
509509

510+
class Meta:
511+
constraints = [
512+
models.UniqueConstraint(
513+
fields=["person", "group"], name="unique_person_group"
514+
)
515+
]
516+
510517
When you set up the intermediary model, you explicitly specify foreign
511518
keys to the models that are involved in the many-to-many relationship. This
512519
explicit declaration defines how the two models are related.
513520

521+
If you don't want multiple associations between the same instances, add a
522+
:class:`~django.db.models.UniqueConstraint` including the ``from`` and ``to``
523+
fields. Django's automatically generated many-to-many tables include such a
524+
constraint.
525+
514526
There are a few restrictions on the intermediate model:
515527

516528
* Your intermediate model must contain one - and *only* one - foreign key

0 commit comments

Comments
 (0)