[Django] #23673: IntegrityError when using a ManyToMany relation to add a model instance with unique constraint.

7 views
Skip to first unread message

Django

unread,
Oct 17, 2014, 10:36:56 AM10/17/14
to django-...@googlegroups.com
#23673: IntegrityError when using a ManyToMany relation to add a model instance
with unique constraint.
-------------------------------------+-------------------------------------
Reporter: jo-soft | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.7
(models, ORM) | Keywords: ManyToManyField,
Severity: Normal | get_or_create
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
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

--
Ticket URL: <https://code.djangoproject.com/ticket/23673>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Oct 19, 2014, 11:48:48 AM10/19/14
to django-...@googlegroups.com
#23673: IntegrityError when using a ManyToMany relation to add a model instance
with unique constraint.
-------------------------------------+-------------------------------------
Reporter: jo-soft | Owner: nobody
Type: Bug | Status: closed

Component: Database layer | Version: 1.7
(models, ORM) | Resolution:
Severity: Normal | worksforme
Keywords: ManyToManyField, | Triage Stage:
get_or_create | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by bmispelon):

* status: new => closed
* needs_better_patch: => 0
* resolution: => worksforme
* needs_tests: => 0
* needs_docs: => 0


Comment:

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.

--
Ticket URL: <https://code.djangoproject.com/ticket/23673#comment:1>

Django

unread,
Oct 20, 2014, 3:45:37 AM10/20/14
to django-...@googlegroups.com
#23673: IntegrityError when using a ManyToMany relation to add a model instance
with unique constraint.
-------------------------------------+-------------------------------------
Reporter: jo-soft | Owner: nobody
Type: Bug | Status: closed

Component: Database layer | Version: 1.7
(models, ORM) | Resolution:
Severity: Normal | worksforme
Keywords: ManyToManyField, | Triage Stage:
get_or_create | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by jo-soft):

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

--
Ticket URL: <https://code.djangoproject.com/ticket/23673#comment:2>

Reply all
Reply to author
Forward
0 new messages