#37027: refresh_from_db() with from_queryset + prefetch does not persist result in
instance
-------------------------------------+-------------------------------------
Reporter: Hugo Maingonnat | Owner: (none)
Type: Bug | Status: closed
Component: Database layer | Version: 5.2
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: refresh_from_db, | Triage Stage:
prefetch | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):
* resolution: => wontfix
* status: new => closed
Comment:
Simon's doubts are convincing. If helpful, I'll add that I had a need for
this in a project (I had a tree of objects shaped via custom
`Prefetch(to_attr=...)` that I needed to be able to refresh), and I found
an involved workaround. Thanks to your ticket, I had the idea to retry
after #28455 (Django 6.1), and there's now a much simpler workaround.
Just prevent the `from_queryset` from being cloned, and then the prefetch
result is still accessible to you, and in your override of
`Model.refresh_from_db` you can put it where you expect it.
{{{#!py
In [1]: admin = User.objects.get(username='admin')
In [2]: reset_queries()
In [3]: from_queryset = User.objects.prefetch_related("groups")
In [4]: with from_queryset._avoid_cloning():
...: admin.refresh_from_db(from_queryset=from_queryset)
...:
In [5]: from_queryset[0]._prefetched_objects_cache
Out[5]: {'groups': <QuerySet [<Group: Graph Editor>, <Group: Resource
Editor>, <Group: RDM Administrator>, <Group: Application Administrator>,
<Group: System Administrator>, <Group: Mobile Project Administrator>,
<Group: Crowdsource Editor>, <Group: Guest>, <Group: Resource Reviewer>,
<Group: Resource Exporter>]>}
In [6]: connection.queries
Out[6]:
[{'sql': 'SELECT "auth_user"."id", "auth_user"."password",
"auth_user"."last_login", "auth_user"."is_superuser",
"auth_user"."username", "auth_user"."first_name", "auth_user"."last_name",
"auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active",
"auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 1
LIMIT 21',
'time': '0.005'},
{'sql': 'SELECT ("auth_user_groups"."user_id") AS
"_prefetch_related_val_user_id", "auth_group"."id", "auth_group"."name"
FROM "auth_group" INNER JOIN "auth_user_groups" ON ("auth_group"."id" =
"auth_user_groups"."group_id") WHERE "auth_user_groups"."user_id" IN (1)',
'time': '0.004'}]
}}}
--
Ticket URL: <
https://code.djangoproject.com/ticket/37027#comment:3>