mirror of
https://github.com/django/django.git
synced 2025-06-05 03:29:12 +00:00
[3.1.x] Fixed #31773 -- Fixed preserving output_field in ExpressionWrapper for combined expressions.
Thanks Thodoris Sotiropoulos for the report and Simon Charette for the implementation idea. Regression in df32fd42b84cc6dbba173201f244491b0d154a63. Backport of 8a6df55f2dd5131282084a4edfd48f63fbf8c69a from master
This commit is contained in:
parent
b19372952c
commit
e6285cac83
@ -857,9 +857,6 @@ 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):
|
||||
@ -869,7 +866,9 @@ class ExpressionWrapper(Expression):
|
||||
return [self.expression]
|
||||
|
||||
def get_group_by_cols(self, alias=None):
|
||||
return self.expression.get_group_by_cols(alias=alias)
|
||||
expression = self.expression.copy()
|
||||
expression.output_field = self.output_field
|
||||
return expression.get_group_by_cols(alias=alias)
|
||||
|
||||
def as_sql(self, compiler, connection):
|
||||
return self.expression.as_sql(compiler, connection)
|
||||
|
@ -6,8 +6,8 @@ from django.core.exceptions import FieldDoesNotExist, FieldError
|
||||
from django.db import connection
|
||||
from django.db.models import (
|
||||
BooleanField, Case, CharField, Count, DateTimeField, Exists,
|
||||
ExpressionWrapper, F, Func, IntegerField, Max, NullBooleanField, OuterRef,
|
||||
Q, Subquery, Sum, Value, When,
|
||||
ExpressionWrapper, F, FloatField, Func, IntegerField, Max,
|
||||
NullBooleanField, OuterRef, Q, Subquery, Sum, Value, When,
|
||||
)
|
||||
from django.db.models.expressions import RawSQL
|
||||
from django.db.models.functions import Length, Lower
|
||||
@ -178,6 +178,14 @@ class NonAggregateAnnotationTestCase(TestCase):
|
||||
self.assertEqual(book.combined, 12)
|
||||
self.assertEqual(book.rating_count, 1)
|
||||
|
||||
def test_combined_f_expression_annotation_with_aggregation(self):
|
||||
book = Book.objects.filter(isbn='159059725').annotate(
|
||||
combined=ExpressionWrapper(F('price') * F('pages'), output_field=FloatField()),
|
||||
rating_count=Count('rating'),
|
||||
).first()
|
||||
self.assertEqual(book.combined, 13410.0)
|
||||
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'))
|
||||
|
Loading…
x
Reference in New Issue
Block a user