Opened 3 years ago
Last modified 3 years ago
#33209 closed Bug
ManyToManyField.add() doesn't respect a unique constraint in intermediate table — at Version 5
Reported by: | Yuta Okamoto | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I added the following Company
and Member
models, and CompanyMember
as their intermediate table with a unique constraint including role
field in addition to through_fields
.
from django.db import models class Company(models.Model): pass class Member(models.Model): companies = models.ManyToManyField(Company, through='CompanyMember', through_fields=('company', 'member'), related_name='members') class CompanyMember: company = models.ForeignKey(Company, on_delete=models.CASCADE) member = models.ForeignKey(Member, on_delete=models.CASCADE) role = models.SmallIntegerField() class Meta: constraints = [ models.UniqueConstraint(fields=['company', 'member', 'role'], name='company_member_role'), ]
In this situation, company.members.add()
silently fails to add existing member with different role specified via through_defaults
.
company = Company.objects.create() member = Member.objects.create() company.members.add(member, through_defaults={'role': 1}) assert company.members.through.objects.all().count() == 1 company.members.add(member, through_defaults={'role': 2}) assert company.members.through.objects.all().count() == 2 # fails
We need to workaround by adding the relation to the intermediate table directly.
company.members.through.objects.create(company=company, member=member, role=2)
Change History (5)
comment:1 by , 3 years ago
Description: | modified (diff) |
---|
comment:2 by , 3 years ago
Description: | modified (diff) |
---|
comment:3 by , 3 years ago
Description: | modified (diff) |
---|
comment:4 by , 3 years ago
Description: | modified (diff) |
---|
comment:5 by , 3 years ago
Description: | modified (diff) |
---|
Note:
See TracTickets
for help on using tickets.