From 0719edcd5fed56157ffb3323a8f634aa5e8f9a80 Mon Sep 17 00:00:00 2001 From: James Timmins Date: Thu, 19 Sep 2019 19:20:40 -0700 Subject: [PATCH] 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. --- AUTHORS | 1 + django/db/models/lookups.py | 6 +++--- tests/lookup/tests.py | 13 +++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index 460bb9a7df3..87011bf1e85 100644 --- a/AUTHORS +++ b/AUTHORS @@ -384,6 +384,7 @@ answer newbie questions, and generally made Django that much better: James Bennett James Murty James Tauber + James Timmins James Wheare Jannis Leidel Janos Guljas diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py index 105dc932513..2683d8971ae 100644 --- a/django/db/models/lookups.py +++ b/django/db/models/lookups.py @@ -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 ' diff --git a/tests/lookup/tests.py b/tests/lookup/tests.py index a603824c0d6..1958b995b2e 100644 --- a/tests/lookup/tests.py +++ b/tests/lookup/tests.py @@ -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)