在通过Django的ORM进行聚合方面,我有一个小问题。我的模型草图非常简单,带有一些自定义字段类型(但这些类型与问题无关):
字段类型
class MoneyField(models.DecimalField):
def __init__(self, *args, **kwargs):
kwargs['null'] = True
kwargs['blank'] = True
kwargs['max_digits'] = 15
kwargs['decimal_places'] = 2
super().__init__(*args, **kwargs)
class RevenueField(MoneyField):
def __init__(self, *args, **kwargs):
kwargs['validators'] = [MinValueValidator(0)]
kwargs['null'] = True
kwargs['blank'] = True
super().__init__(*args, **kwargs)
class WeakTextField(models.CharField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 200
kwargs['null'] = True
kwargs['blank'] = True
super().__init__(*args, **kwargs)
class NameField(WeakTextField):
def __init__(self, *args, **kwargs):
kwargs['unique'] = True
super().__init__(*args, **kwargs)
class YearField(models.PositiveIntegerField):
def __init__(self, *args, **kwargs):
kwargs['validators'] = [
MinValueValidator(1900),
MaxValueValidator(2100),
]
kwargs['null'] = True
kwargs['blank'] = True
super().__init__(*args, **kwargs)
class WeakForeignKey(models.ForeignKey):
def __init__(self, *args, **kwargs):
kwargs['null'] = True
kwargs['blank'] = True
kwargs['on_delete'] = models.SET_NULL
super().__init__(*args, **kwargs)
模型实体
class Company(models.Model):
registration_number = NameField(_('Registration number')) # custom field, defined above
name = NameField(_('Name'))
...
..
.
class Financial(models.Model):
financial_year = YearField(_('Financial year'))
company = WeakForeignKey(to='Company', verbose_name=_('Company'))
revenue = RevenueField(_('Revenue'))
...
..
.
class Meta:
unique_together = (('financial_year', 'company'),)
我的目标是使用QuerySet编写这样的查询:
SELECT financial_year, SUM(revenue)
FROM financial
GROUP BY financial_year
据我所知,ORM应该这样完成:
qs = Financial.objects.values('financial_year').annotate(Sum('revenue'))
但是,如果我打印出SQL查询,则在Group By语句之后会有一个额外的"data_manager_company"."name"
字段:
SELECT
"data_manager_financial"."financial_year",
CAST(SUM("data_manager_financial"."revenue") AS NUMERIC) AS "revenue__sum"
FROM "data_manager_financial"
LEFT OUTER JOIN "data_manager_company"
ON ("data_manager_financial"."company_id" = "data_manager_company"."id")
GROUP BY
"data_manager_financial"."financial_year",
"data_manager_company"."name"
ORDER BY "data_manager_company"."name"
ASC, "data_manager_financial"."financial_year" ASC
恐怕这个问题与金融实体的独特约束有关。当然,可以通过原始SQL或通过财政年度字段的单独实体解决问题,但我不喜欢它们。你有什么想法吗?
非常感谢!
Gallusz
答案 0 :(得分:1)
我认为这更多是因为您注释每个单独的对象。因此,结果相同 'financial_year'
在您的查询中将发生多次次。
这些年来,您可以将 .order_by(..)
声明“ 折叠”成一个条目,我听起来很奇怪:
qs = Financial.objects.values(
'financial_year'
).annotate(
Sum('revenue')
).order_by(
'financial_year'
)
因此,在这里,我们指示Django仅使用'financial_year'
作为石斑鱼,因此在每个Sum(..)
的{{1}}上使用'revenue'
。