问题描述
|
大家好,我有一个看起来像这样的模型:
class Interaction(DateAwareModel,UserAwareModel):
page = models.ForeignKey(Page)
container = models.ForeignKey(Container,blank=True,null=True)
content = models.ForeignKey(Content)
interaction_node = models.ForeignKey(InteractionNode)
kind = models.CharField(max_length=3,choices=INteraCTION_TYPES)
我希望能够执行一个查询来获取按容器然后按种类分组的交互计数。这个想法是输出JSON数据结构(串行化由活塞负责)看起来像这样:
\"data\": {
\"container 1\": {
\"tag_count\": 3,\"com_count\": 1
},\"container 2\": {
\"tag_count\": 7,\"com_count\": 12
},...
}
sql看起来像这样:
SELECT container_id,kind,count(*) FROM rb_interaction GROUP BY container_id,kind;
关于如何使用ORM按多个字段分组的任何想法? (如果可以避免使用id,我不想为此项目编写原始查询)这似乎是一个简单而常见的查询。
在您问之前:我已经看过django聚合文档和原始查询文档。
更新资料
根据以下建议,我创建了一个自定义管理器来处理此问题:
class ContainerManager(models.Manager):
def get_query_set(self,*args,**kwargs):
qs = super(ContainerManager,self).get_query_set(*args,**kwargs)
qs.filter(Q(interaction__kind=\'tag\') | Q(interaction__kind=\'com\')).distinct()
annotations = {
\'tag_count\':models.Count(\'interaction__kind\'),\'com_count\':models.Count(\'interaction__kind\')
}
return qs.annotate(**annotations)
这仅计算标签或com类型的交互,而不是通过group by检索标签和com的计数。很明显,它可以从代码中以这种方式工作,但是想知道如何解决它...
解决方法
创建一个自定义管理器:
class ContainerManager(models.Manager):
def get_query_set(self,*args,**kwargs):
qs = super(ContainerManager,self).get_query_set(*args,**kwargs)
annotations = {\'tag_count\':models.Count(\'tag\'),\'com_count\':models.Count(\'com\')}
return qs.annotate(**annotations)
class Container(models.Model):
...
objects = ContainerManager()
然后,“ 5”查询将始终包含“ 6”和“ 7”属性。您可能需要修改批注,因为我没有要引用的模型副本;我只是猜测字段名称。
更新:
因此,在对模型有了更好的了解之后,注释将无法满足您的需求。真正获得计数的只有5个具有\'tag \'或\'com \'的9个s的计数是:
tag_count = Container.objects.filter(kind=\'tag\').count()
com_count = Container.objects.filter(kind=\'com\').count()
注释不会为您提供该信息。我认为可以编写自己的聚合和注释,所以这可能是一种解决方案。但是,我从来没有自己做过,所以我真的不能给您任何指导。您可能会坚持使用直接SQL。