Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#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 Baptiste Mispelon, 10 years ago

Resolution: worksforme
Status: newclosed

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 to M2.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 in m.m2m, then by definition get_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.

comment:2 by j_schn14, 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

Note: See TracTickets for help on using tickets.
Back to Top