Opened 9 months ago
Last modified 9 months ago
#35317 closed New feature
Add the possibility to do prefetches for only a subset of instances — at Initial Version
Reported by: | Laurent Lyaudet | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 5.0 |
Severity: | Normal | Keywords: | |
Cc: | Laurent Lyaudet | Triage Stage: | Unreviewed |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hello,
I have use cases with serializers returning a lot of distinct informations.
For example, my serialiser can be called with many=True and a query of 2000 Order instances.
And for a small part of these 2000 instances, I need very expensive prefetches.
Currently, I deal with that by overloading the _fetch_all() method and make by hand the hyper-specifics and expensive prefetches,
after everything else.
What I propose is to add a filter_callback kwarg to Prefetch object.
filter_callback would be either None (default) or a function taking only one instance of the previous level of prefetch
and return a boolean to know if the instance needs that prefetch.
A simple example is when you will filter on some status field of Order,
but in that case, you can just modify the query somehow.
And unfortunately, the order id would still be injected in the prefetch query.
But for more realistic examples, you do not want to recode the business logic
in the SQL query to know what needs the prefetch or not.
Example :
orders = ( Order.objects.filter(...) .exclude(...) .annotate(...) .prefetch_related( "items", "address", Prefetch( "packing_task__zonings", queryset=Zonings.objects.filter(...), filter_callback=lambda packing_task: packing_task.order.needs_to_consider_packing_problematic_zonings(), to="problematic_zonings", ) )
Best regards,
Laurent Lyaudet