feat: support select_related and prefetch_related for inherited models#893
Open
huynguyengl99 wants to merge 4 commits into
Open
feat: support select_related and prefetch_related for inherited models#893huynguyengl99 wants to merge 4 commits into
huynguyengl99 wants to merge 4 commits into
Conversation
Contributor
Author
|
If this looks good, I think it could go out as 4.12 rather than a 5.0 bump — the changes are fully backward compatible. Existing |
Member
|
@huynguyengl99 thanks for this, I'll look at it asap |
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi @bckohan (and other devs), the
select_relatedandprefetch_relatedsupport for inherited models has been requested for a long time but hasn't been merged yet despite some pending PRs (#545, #531), so I decided to implement it. It's working well in my project. Hope you guys can find time to review it so it could be merged — I've really wanted this feature for a while.Summary
Add
select_relatedandprefetch_relatedsupport for inherited/child models using the existingModelName___fieldsyntax.Child-specific fields are only applied when re-fetching instances of the matching child class, avoiding unnecessary JOINs on other subtypes. The
___syntax is consistent withfilter(),order_by(),defer(), andonly().How it works
select_related()andprefetch_related()are overridden to parseModelName___fieldlookups. Child-specific configs are stored on the queryset and applied per-child in_get_real_instances(). Grandchild models inherit configs viaissubclass. Handlesonly()/defer()interaction by auto-including FK fields in the non-deferred set.vs prior PRs
vs #545 — #545 takes a more ambitious approach by rewriting the iterator and
RelatedPopulatorto also support non-poly → poly FK traversal — a great goal. This PR takes a lighter approach (~80 lines, plugging into the existing_get_real_instances()flow) to cover the most common use cases first. The non-poly → poly FK case from #545 could be added on top of this separately.vs #531 — #531 adds new methods (
select_polymorphic_related) rather than extending existing ones. This PR extendsselect_related/prefetch_relateddirectly — no new API to learn, consistent with how___already works infilter()andorder_by(). Also adds handling foronly()/defer()interaction,Prefetchobjects,to_attr, and clearing withNone.Issues addressed
Closes #198, #436, #498, #641. Partially addresses #410, #359, #545.
Test plan
select_related/prefetch_relatedpre-loads relations (0 extra queries)Prefetchobject with custom queryset andto_attrNone, combined select + prefetchonly()+ child-specificselect_relatedselect_relatedpreserved after downcastAlso tested against a production Django+DRF codebase with N+1 detection — working as expected.