[Django] #34141: Prefetch querysets access to parent query through table

26 views
Skip to first unread message

Django

unread,
Nov 4, 2022, 1:00:17 PM11/4/22
to django-...@googlegroups.com
#34141: Prefetch querysets access to parent query through table
-----------------------------------------+--------------------------------
Reporter: nixj14 | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 4.1
Severity: Normal | Keywords: QuerySet.extra
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+--------------------------------
In working on a project recently, I ran into the following use-case:
1) A parent model exists with a ManyToMany field.
2) This field goes through a ManyToMany table.
3) The ManyToMany table has an attribute that I'm interested in filtering
on.

I'm my use-case (see attached sample code), I'm wanting to query out
parent objects and then prefetch the child associated list (in this case
locations). Prefetching is able to pull through the child associated
list. My problem is that I need to constrain on an attribute that is
defined in the through table (record_status). I do not have the luxary of
being able to update my model, so I was looking for ways I could define my
prefetch so that it would return back the correct associated records, but
with the additional filter. The only way I could figure out how to make
it work, was to use the extra query. Anytime I tried to add filtering
logic in the prefetch that referenced CompanyLocation, I would get an
error about an invalid attribute. If I tried adding the criteria onto the
Company objects portion, it would not fail compilation, but would fail
querying due to multiple records being returned. It didn't make sense to
me to include it there anyway as I was not trying to constrain the Company
records, but the location records collection that was being prefetched.

Maybe there is a way of doing this that I didn't find. If not, I think it
would be a good use-case to be able to make references to the through
object in the prefetch itself.

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

Django

unread,
Nov 4, 2022, 1:00:35 PM11/4/22
to django-...@googlegroups.com
#34141: Prefetch querysets access to parent query through table
--------------------------------+--------------------------------------

Reporter: nixj14 | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 4.1
Severity: Normal | Resolution:

Keywords: QuerySet.extra | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------------------------
Changes (by nixj14):

* Attachment "models.py" added.

Django

unread,
Nov 4, 2022, 3:07:12 PM11/4/22
to django-...@googlegroups.com
#34141: Prefetch querysets access to parent query through table
--------------------------------+--------------------------------------
Reporter: Jeremy Nix | Owner: nobody
Type: Uncategorized | Status: closed
Component: Uncategorized | Version: 4.1
Severity: Normal | Resolution: invalid

Keywords: QuerySet.extra | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------------------------
Changes (by Simon Charette):

* status: new => closed
* resolution: => invalid


Comment:

Please don't use this ticket tracker as a support channel
TicketClosingReasons/UseSupportChannels.

Just like any queryset the ones provided to `Prefetch` can be filtered
against reverse foreign keys.

In your case, since you've defined `CompanyLocation.location.related_name
= "companies"`, that means you can do
`filter(companies__record_status="Active')` to achieve the same result as
your `extra`. I suggest adding a more adequate name of
`CompanyLocation.location.related_name = "company_locations"` to avoid
ambiguity with the reverse relationship added to `Company.locations`.

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

Reply all
Reply to author
Forward
0 new messages