Opened 4 months ago

Closed 4 months ago

Last modified 4 months ago

#34612 closed Bug (fixed)

QuerySet.only() doesn't work with select_related() on a reverse OneToOneField relation.

Reported by: Ian Cubitt Owned by: Simon Charette
Component: Database layer (models, ORM) Version: 4.2
Severity: Release blocker Keywords:
Cc: Simon Charette Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

On Django 4.2 calling only() with select_related() on a query using the reverse lookup for a OneToOne relation does not generate the correct query.
All the fields from the related model are still included in the generated SQL.

Sample models:

class Main(models.Model):
    main_field_1 = models.CharField(blank=True, max_length=45)
    main_field_2 = models.CharField(blank=True, max_length=45)
    main_field_3 = models.CharField(blank=True, max_length=45)


class Secondary(models.Model):
    main = models.OneToOneField(Main, primary_key=True, related_name='secondary', on_delete=models.CASCADE)
    secondary_field_1 = models.CharField(blank=True, max_length=45)
    secondary_field_2 = models.CharField(blank=True, max_length=45)
    secondary_field_3 = models.CharField(blank=True, max_length=45)

Sample code:

Main.objects.select_related('secondary').only('main_field_1', 'secondary__secondary_field_1')

Generated query on Django 4.2.1:

SELECT "bugtest_main"."id", "bugtest_main"."main_field_1", "bugtest_secondary"."main_id", "bugtest_secondary"."secondary_field_1", "bugtest_secondary"."secondary_field_2", "bugtest_secondary"."secondary_field_3" FROM "bugtest_main" LEFT OUTER JOIN "bugtest_secondary" ON ("bugtest_main"."id" = "bugtest_secondary"."main_id")

Generated query on Django 4.1.9:

SELECT "bugtest_main"."id", "bugtest_main"."main_field_1", "bugtest_secondary"."main_id", "bugtest_secondary"."secondary_field_1" FROM "bugtest_main" LEFT OUTER JOIN "bugtest_secondary" ON ("bugtest_main"."id" = "bugtest_secondary"."main_id")

Change History (6)

comment:1 Changed 4 months ago by Mariusz Felisiak

Cc: Simon Charette added
Severity: NormalRelease blocker
Summary: QuerySet.only() regression on Django 4.2 with select_related() on a reverse OneToOneField relationQuerySet.only() doesn't work with select_related() on a reverse OneToOneField relation.
Triage Stage: UnreviewedAccepted

Thanks for the report!

Regression in b3db6c8dcb5145f7d45eff517bcd96460475c879.
Reproduced at 881cc139e2d53cc1d3ccea7f38faa960f9e56597.

comment:2 Changed 4 months ago by Simon Charette

Owner: changed from nobody to Simon Charette
Status: newassigned

comment:3 Changed 4 months ago by Simon Charette

Has patch: set

comment:4 Changed 4 months ago by Mariusz Felisiak

Triage Stage: AcceptedReady for checkin

comment:5 Changed 4 months ago by Mariusz Felisiak <felisiak.mariusz@…>

Resolution: fixed
Status: assignedclosed

In 2cf76f2d:

Fixed #34612 -- Fixed QuerySet.only() crash on reverse relationships.

Regression in b3db6c8dcb5145f7d45eff517bcd96460475c879.

Thanks Ian Cubitt for the report.

This also corrected test_inheritance_deferred2() test which was
previously properly defined and marked as an expected failure but was
then wrongly adjusted to mask the lack of support for per-alias
deferral that was fixed by #21204.

comment:6 Changed 4 months ago by Mariusz Felisiak <felisiak.mariusz@…>

In 7383864:

[4.2.x] Fixed #34612 -- Fixed QuerySet.only() crash on reverse relationships.

Regression in b3db6c8dcb5145f7d45eff517bcd96460475c879.

Thanks Ian Cubitt for the report.

This also corrected test_inheritance_deferred2() test which was
previously properly defined and marked as an expected failure but was
then wrongly adjusted to mask the lack of support for per-alias
deferral that was fixed by #21204.

Backport of 2cf76f2d5d1aa16acfadaf53db3d30128a34b088 from main

Note: See TracTickets for help on using tickets.
Back to Top