#23673 closed Bug (worksforme)
IntegrityError when using a ManyToMany relation to add a model instance with unique constraint.
Reported by: | j_schn14 | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.7 |
Severity: | Normal | Keywords: | ManyToManyField, get_or_create |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Setting:
- two models connected with a m2m relation. (let's call them m1, m2 and the ralation m1.m2m)
- one of them has a unique relation on one field. (lets say field1)
- creating instances of m2 via m1.m2m.get_or_create works only once for every unique value of field1. independent of the instance of m1.
The get parts tries to get an instance of m2 which is related to m1, which does not exists. this leads to creating a new instance of m2 with field equals the value used above. this already exists and leads to a IntegrityError.
See this minimal example:
http://pastebin.com/eUs1R6fD
Change History (2)
comment:1 by , 10 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
comment:2 by , 10 years ago
Hey,
no, you got me. But I expected that in line 15 there should be called an add
with the existing
foo
on
another_m
s.t. in the end
m
and
another_m
refer to the same M2 instance with the unique name
foo
instead of creating a another instance of
M2
with name foo.
bg,
Johannes
Hi,
It seems to me that things are working as intended.
In your example, when you use
m.m2m
, you basically get a queryset that's equivalent toM2.objects.filter(m1=m)
.So when you do
m.m2m.get_or_create(name='foo')
, you're doing M2.objects.filter(m1=m).get_or_create(name='foo')`.If there's a M2 element with a name
foo
but which doesn't appear inm.m2m
, then by definitionget_or_create
will attempty to create it.This is of course not possible because of the unique constraint on the name, so you get the
IntegrityError
.Closing this as
worksforme
. Please reopen if I've misunderstood your issue.Thanks.