我有这个型号:
class Interaction(models.Model):
user = models.ForeignKey(User)
codes = ArrayField(models.CharField(choices=CODE_CHOICES))
我正在试图弄清楚如何在Django中执行相当于这个SQL查询:
select user_id, sum(cardinality(codes)) from interaction group by user_id;
extra(select={codes_len':'cardinality(codes)'})
,但是你
在annotate
字段上无法aggregate
或extra
。annotate(Sum("cardinality('codes')"))
,但是
cardinality('codes')
不是模型上的字段。Sum
的自定义聚合字段
和cardinality
,但看起来......脆弱。__len
可以正常运行
ArrayField
,但不是在上下文中
annotate(Sum('codes__len'))
。WHERE
语句(这里省略),这使得这个查询难以手工重构。此时我认为我别无选择,只能在模型中添加一个字段,该字段是codes
字段的长度,并与save()
混乱以保持同步。
真的没有别的办法吗?我错过了什么吗?
答案 0 :(得分:2)
事实证明,自定义聚合函数是可行的方法!
以下内容:
from django.db.models import Aggregate
class SumCardinality(Aggregate):
template = 'SUM(CARDINALITY(%(expressions)s))'
查询非常简单:
Interaction.objects().filter(xxx).\
values('user_id').annotate(codes_len=SumCardinality('codes'))