[3.0.x] Fixed #30771 -- Fixed exact lookup against queries with selected columns.

Use pre-existing select fields (and thereby GROUP BY fields) from
subquery if they were specified, instead of always defaulting to pk.

Thanks Aur Saraf for the report and Simon Charette for guidance.

Backport of 0719edcd5f from master
This commit is contained in:
James Timmins 2019-09-19 19:20:40 -07:00 committed by Mariusz Felisiak
parent def1857d9b
commit 3697ddbf75
3 changed files with 17 additions and 3 deletions

View File

@ -384,6 +384,7 @@ answer newbie questions, and generally made Django that much better:
James Bennett <james@b-list.org>
James Murty
James Tauber <jtauber@jtauber.com>
James Timmins <jameshtimmins@gmail.com>
James Wheare <django@sparemint.com>
Jannis Leidel <jannis@leidel.info>
Janos Guljas

View File

@ -262,9 +262,9 @@ class Exact(FieldGetDbPrepValueMixin, BuiltinLookup):
from django.db.models.sql.query import Query
if isinstance(self.rhs, Query):
if self.rhs.has_limit_one():
# The subquery must select only the pk.
self.rhs.clear_select_clause()
self.rhs.add_fields(['pk'])
if not self.rhs.has_select_fields:
self.rhs.clear_select_clause()
self.rhs.add_fields(['pk'])
else:
raise ValueError(
'The QuerySet value for an exact lookup must be limited to '

View File

@ -5,6 +5,7 @@ from operator import attrgetter
from django.core.exceptions import FieldError
from django.db import connection
from django.db.models import Max
from django.db.models.expressions import Exists, OuterRef
from django.db.models.functions import Substr
from django.test import TestCase, skipUnlessDBFeature
@ -956,3 +957,15 @@ class LookupTests(TestCase):
),
)
self.assertEqual(qs.get(has_author_alias_match=True), tag)
def test_exact_query_rhs_with_selected_columns(self):
newest_author = Author.objects.create(name='Author 2')
authors_max_ids = Author.objects.filter(
name='Author 2',
).values(
'name',
).annotate(
max_id=Max('id'),
).values('max_id')
authors = Author.objects.filter(id=authors_max_ids[:1])
self.assertEqual(authors.get(), newest_author)