Opened 4 years ago
Last modified 4 years ago
#33209 closed Bug
ManyToManyField.add() doesn't respect a unique constraint in intermediate table — at Version 1
| 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', 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() 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.objects.all().count() == 1 company.members.add(member, through_defaults={'role': 2}) assert Company.objects.all().count() == 2 # fails
We need to workaround by adding the relation to the intermediate table directly.
company.members.through.objects.create( company.members.through(company=company, member=member, role=2) )
Note:
See TracTickets
for help on using tickets.