mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
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):
|
||||
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):
|
||||
def __repr__(self):
|
||||
|
@ -38,6 +38,7 @@ class Store(models.Model):
|
||||
books = models.ManyToManyField(Book)
|
||||
original_opening = models.DateTimeField()
|
||||
friday_night_closing = models.TimeField()
|
||||
area = models.IntegerField(null=True, db_column='surface')
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -405,6 +405,28 @@ class NonAggregateAnnotationTestCase(TestCase):
|
||||
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):
|
||||
authors = Author.objects.annotate(c=Count('id')).filter(c__gt=1)
|
||||
self.assertFalse(authors.exists())
|
||||
|
Loading…
Reference in New Issue
Block a user