Skip to content

Conversation

@Samriddha9619
Copy link
Contributor

ticket-35442

Branch description

This PR prevents N+1 queries when iterating over a RelatedManager queryset that uses .only() to exclude the foreign key field.

Previously, ModelIterable would attempt to optimize the relationship population by accessing the foreign key on the child object. If that key was deferred (via .only()), accessing it triggered an immediate SQL query for every row.

The fix modifies ModelIterable to check obj.__dict__ first. If the foreign key attributes are missing (deferred), the optimization is skipped, preserving the lazy loading behavior requested by the user.

Tests:

  • Added test_only_related_manager_optimization in defer.tests to verify query count is 1 (previously N+1).
  • Updated defer.tests.DeferTests.test_only to assert the correct number of deferred fields (3 instead of 2), reflecting that the foreign key is now correctly deferred.

Checklist

  • This PR targets the main branch.
  • The commit message is written in past tense, mentions the ticket number, and ends with a period.
  • I have checked the "Has patch" ticket flag in the Trac system.
  • I have added or updated relevant tests.
  • I have added or updated relevant docs, including release notes if applicable.
  • I have attached screenshots in both light and dark modes for any UI changes.

Copy link
Member

@jacobtylerwalls jacobtylerwalls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Since this uses Simon's patch from the ticket comments, please add him as a co-author in the commit message. You can grep the commit log to see how this is done. Also please use two hyphens (not one) in the commit message & PR title. Cheers!

@Samriddha9619 Samriddha9619 changed the title Fixed #35442 - Prevented N+1 queries in RelatedManager with only(). Fixed #35442 -- Prevented N+1 queries in RelatedManager with only(). Jan 5, 2026
@Samriddha9619
Copy link
Contributor Author

@jacobtylerwalls Done

@jacobtylerwalls
Copy link
Member

I think you need another newline before the co-author for the UI to reflect it here (as well as to follow the existing format.)

Co-authored-by: Simon Charette <charette.s@gmail.com>
@Samriddha9619
Copy link
Contributor Author

I think you need another newline before the co-author for the UI to reflect it here (as well as to follow the existing format.)

Fixed. Thanks for pointing that out.

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

📊 Coverage Report for Changed Files

-------------
Diff Coverage
Diff: origin/main...HEAD, staged and unstaged changes
-------------
django/db/models/query.py (100%)
-------------
Total:   3 lines
Missing: 0 lines
Coverage: 100%
-------------


Note: Missing lines are warnings only. Some lines may not be covered by SQLite tests as they are database-specific.

For more information about code coverage on pull requests, see the contributing documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants