[3.1.x] Fixed #31659 -- Made ExpressionWrapper preserve output_field for combined expressions.

Regression in df32fd42b8.

Thanks Simon Charette for the review.

Backport of aeb8996a67 from master
This commit is contained in:
Mariusz Felisiak 2020-06-11 11:29:14 +02:00
parent 45ec013116
commit 42f5f2d76b
3 changed files with 14 additions and 1 deletions

View File

@ -857,6 +857,9 @@ class ExpressionWrapper(Expression):
def __init__(self, expression, output_field):
super().__init__(output_field=output_field)
if getattr(expression, '_output_field_or_none', True) is None:
expression = expression.copy()
expression.output_field = output_field
self.expression = expression
def set_source_expressions(self, exprs):

View File

@ -170,6 +170,14 @@ class NonAggregateAnnotationTestCase(TestCase):
self.assertEqual(book.is_book, 1)
self.assertEqual(book.rating_count, 1)
def test_combined_expression_annotation_with_aggregation(self):
book = Book.objects.annotate(
combined=ExpressionWrapper(Value(3) * Value(4), output_field=IntegerField()),
rating_count=Count('rating'),
).first()
self.assertEqual(book.combined, 12)
self.assertEqual(book.rating_count, 1)
def test_aggregate_over_annotation(self):
agg = Author.objects.annotate(other_age=F('age')).aggregate(otherage_sum=Sum('other_age'))
other_agg = Author.objects.aggregate(age_sum=Sum('age'))

View File

@ -1837,4 +1837,6 @@ class ExpressionWrapperTests(SimpleTestCase):
def test_non_empty_group_by(self):
expr = ExpressionWrapper(Lower(Value('f')), output_field=IntegerField())
self.assertEqual(expr.get_group_by_cols(alias=None), [expr.expression])
group_by_cols = expr.get_group_by_cols(alias=None)
self.assertEqual(group_by_cols, [expr.expression])
self.assertEqual(group_by_cols[0].output_field, expr.output_field)