Fixed #28289 -- Fixed crash of RawSQL annotations on inherited model fields.
This commit is contained in:
parent
a9c6ab0356
commit
52545e788d
|
@ -699,6 +699,16 @@ class RawSQL(Expression):
|
||||||
def get_group_by_cols(self, alias=None):
|
def get_group_by_cols(self, alias=None):
|
||||||
return [self]
|
return [self]
|
||||||
|
|
||||||
|
def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
|
||||||
|
# Resolve parents fields used in raw SQL.
|
||||||
|
for parent in query.model._meta.get_parent_list():
|
||||||
|
for parent_field in parent._meta.local_fields:
|
||||||
|
_, column_name = parent_field.get_attname_column()
|
||||||
|
if column_name.lower() in self.sql.lower():
|
||||||
|
query.resolve_ref(parent_field.name, allow_joins, reuse, summarize)
|
||||||
|
break
|
||||||
|
return super().resolve_expression(query, allow_joins, reuse, summarize, for_save)
|
||||||
|
|
||||||
|
|
||||||
class Star(Expression):
|
class Star(Expression):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
|
@ -38,6 +38,7 @@ class Store(models.Model):
|
||||||
books = models.ManyToManyField(Book)
|
books = models.ManyToManyField(Book)
|
||||||
original_opening = models.DateTimeField()
|
original_opening = models.DateTimeField()
|
||||||
friday_night_closing = models.TimeField()
|
friday_night_closing = models.TimeField()
|
||||||
|
area = models.IntegerField(null=True, db_column='surface')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
|
@ -405,6 +405,28 @@ class NonAggregateAnnotationTestCase(TestCase):
|
||||||
lambda a: (a['age'], a['age_count'])
|
lambda a: (a['age'], a['age_count'])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_raw_sql_with_inherited_field(self):
|
||||||
|
DepartmentStore.objects.create(
|
||||||
|
name='Angus & Robinson',
|
||||||
|
original_opening=datetime.date(2014, 3, 8),
|
||||||
|
friday_night_closing=datetime.time(21),
|
||||||
|
chain='Westfield',
|
||||||
|
area=123,
|
||||||
|
)
|
||||||
|
tests = (
|
||||||
|
('name', 'Angus & Robinson'),
|
||||||
|
('surface', 123),
|
||||||
|
("case when name='Angus & Robinson' then chain else name end", 'Westfield'),
|
||||||
|
)
|
||||||
|
for sql, expected_result in tests:
|
||||||
|
with self.subTest(sql=sql):
|
||||||
|
self.assertSequenceEqual(
|
||||||
|
DepartmentStore.objects.annotate(
|
||||||
|
annotation=RawSQL(sql, ()),
|
||||||
|
).values_list('annotation', flat=True),
|
||||||
|
[expected_result],
|
||||||
|
)
|
||||||
|
|
||||||
def test_annotate_exists(self):
|
def test_annotate_exists(self):
|
||||||
authors = Author.objects.annotate(c=Count('id')).filter(c__gt=1)
|
authors = Author.objects.annotate(c=Count('id')).filter(c__gt=1)
|
||||||
self.assertFalse(authors.exists())
|
self.assertFalse(authors.exists())
|
||||||
|
|
Loading…
Reference in New Issue