1
0
mirror of https://github.com/django/django.git synced 2024-12-23 01:25:58 +00:00

Fixed #33975 -- Fixed __in lookup when rhs is a queryset with annotate() and alias().

This fixes clearing selected fields.
This commit is contained in:
DevilsAutumn 2022-09-06 15:22:41 +05:30 committed by Mariusz Felisiak
parent 0c3981eb50
commit 32797e7fbf
3 changed files with 31 additions and 8 deletions

View File

@ -93,7 +93,6 @@ class RelatedIn(In):
elif not getattr(self.rhs, "has_select_fields", True) and not getattr( elif not getattr(self.rhs, "has_select_fields", True) and not getattr(
self.lhs.field.target_field, "primary_key", False self.lhs.field.target_field, "primary_key", False
): ):
self.rhs.clear_select_clause()
if ( if (
getattr(self.lhs.output_field, "primary_key", False) getattr(self.lhs.output_field, "primary_key", False)
and self.lhs.output_field.model == self.rhs.model and self.lhs.output_field.model == self.rhs.model
@ -105,7 +104,7 @@ class RelatedIn(In):
target_field = self.lhs.field.name target_field = self.lhs.field.name
else: else:
target_field = self.lhs.field.target_field.name target_field = self.lhs.field.target_field.name
self.rhs.add_fields([target_field], True) self.rhs.set_values([target_field])
return super().get_prep_lookup() return super().get_prep_lookup()
def as_sql(self, compiler, connection): def as_sql(self, compiler, connection):

View File

@ -198,6 +198,7 @@ class Query(BaseExpression):
select_for_update_of = () select_for_update_of = ()
select_for_no_key_update = False select_for_no_key_update = False
select_related = False select_related = False
has_select_fields = False
# Arbitrary limit for select_related to prevents infinite recursion. # Arbitrary limit for select_related to prevents infinite recursion.
max_depth = 5 max_depth = 5
# Holds the selects defined by a call to values() or values_list() # Holds the selects defined by a call to values() or values_list()
@ -263,12 +264,6 @@ class Query(BaseExpression):
elif len(self.annotation_select) == 1: elif len(self.annotation_select) == 1:
return next(iter(self.annotation_select.values())).output_field return next(iter(self.annotation_select.values())).output_field
@property
def has_select_fields(self):
return bool(
self.select or self.annotation_select_mask or self.extra_select_mask
)
@cached_property @cached_property
def base_table(self): def base_table(self):
for alias in self.alias_map: for alias in self.alias_map:
@ -2384,6 +2379,7 @@ class Query(BaseExpression):
self.select_related = False self.select_related = False
self.clear_deferred_loading() self.clear_deferred_loading()
self.clear_select_fields() self.clear_select_fields()
self.has_select_fields = True
if fields: if fields:
field_names = [] field_names = []

View File

@ -989,6 +989,34 @@ class NonAggregateAnnotationTestCase(TestCase):
publisher_books_qs, [{"name": "Sams"}, {"name": "Morgan Kaufmann"}] publisher_books_qs, [{"name": "Sams"}, {"name": "Morgan Kaufmann"}]
) )
def test_annotation_and_alias_filter_in_subquery(self):
awarded_publishers_qs = (
Publisher.objects.filter(num_awards__gt=4)
.annotate(publisher_annotate=Value(1))
.alias(publisher_alias=Value(1))
)
qs = Publisher.objects.filter(pk__in=awarded_publishers_qs)
self.assertCountEqual(qs, [self.p3, self.p4])
def test_annotation_and_alias_filter_related_in_subquery(self):
long_books_qs = (
Book.objects.filter(pages__gt=400)
.annotate(book_annotate=Value(1))
.alias(book_alias=Value(1))
)
publisher_books_qs = Publisher.objects.filter(
book__in=long_books_qs,
).values("name")
self.assertCountEqual(
publisher_books_qs,
[
{"name": "Apress"},
{"name": "Sams"},
{"name": "Prentice Hall"},
{"name": "Morgan Kaufmann"},
],
)
def test_annotation_exists_aggregate_values_chaining(self): def test_annotation_exists_aggregate_values_chaining(self):
qs = ( qs = (
Book.objects.values("publisher") Book.objects.values("publisher")