#36235: RelatedManager.all().get_or_create() does not work
-------------------------------------+-------------------------------------
Reporter: Nick Pope | Owner: (none)
Type: Bug | Status: new
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: get_or_create, | Triage Stage:
related, manager | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Nick Pope:
Old description:
> When accessing the queryset for a related manager, `.get_or_create()` and
> `.update_or_create()` lose context of the related instance.
>
> Calling on the related manager works as expected:
>
> {{{#!python
> publisher.books.get_or_create(name="The Very Hungry Caterpillar")
> }}}
>
> This is the case that was fixed by #3121 and #23611.
>
> But calling on the queryset causes an `IntegrityError` to be raised:
>
> {{{#!python
> publisher.books.all().get_or_create(name="The Very Hungry Caterpillar")
> }}}
>
> This can be a subtle failure that is hard to understand, especially if
> `publisher.books.all()` is assigned to a variable earlier.
>
> The challenge here is that the overridden methods on the manager set
> `kwargs[self.field.name] = self.instance`.
>
> We'd need to be able to pass this information down to the queryset. It
> looks like this might already be available in `_known_related_objects`
> which is set by `RelatedManager._apply_rel_filters()`, so that would be a
> good starting point for investigation.
>
> If this is something we can't fix reliably, then we should update the
> admonition under
> [https://docs.djangoproject.com/en/stable/ref/models/querysets/#get-or-
> create .get_or_create()] in the docs and probably update
> [https://docs.djangoproject.com/en/stable/ref/models/querysets/#update-
> or-create .update_or_create()] to make this and other issues related to
> use through `RelatedManager` more clear.
New description:
When accessing the queryset for a related manager, `.get_or_create()` and
`.update_or_create()` lose context of the related instance.
Calling on the related manager works as expected:
{{{#!python
publisher.books.get_or_create(name="The Very Hungry Caterpillar")
}}}
This is the case that was fixed by #3121 and #23611.
But calling on the queryset causes an `IntegrityError` to be raised:
{{{#!python
publisher.books.all().get_or_create(name="The Very Hungry Caterpillar")
}}}
This can be a subtle failure that is hard to understand, especially if
`publisher.books.all()` is assigned to a variable earlier.
The challenge here is that the overridden methods on the manager set
`kwargs[self.field.name] = self.instance`.
We'd need to be able to pass this information down to the queryset. It
looks like this might already be available in `_known_related_objects`
which is set by `RelatedManager._apply_rel_filters()`, so that would be a
good starting point for investigation.
We would also need to check whether something needs to be done to select
the correct database as `RelatedManager.get_or_create()` has handling for
this:
{{{#!python
db = router.db_for_write(self.model, instance=self.instance)
}}}
If this is something we can't fix reliably, then we should update the
admonition under
[https://docs.djangoproject.com/en/stable/ref/models/querysets/#get-or-
create .get_or_create()] in the docs and probably update
[https://docs.djangoproject.com/en/stable/ref/models/querysets/#update-or-
create .update_or_create()] to make this and other issues related to use
through `RelatedManager` more clear.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/36235#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/django-updates/01070195705d2f3d-cf4fb62b-c4fe-46b3-96e3-13f1b5073882-000000%40eu-central-1.amazonses.com.