我有两个型号' ModelParent'和' ModelChild',其中' ModelParent'有很多' ModelChild',这是我的模型结构:
class ModelParent(models.Model):
... some params ...
class ModelChild(models.Model):
TYPES = (
(1, 'First'),
(2, 'Second'),
)
parent = models.ForeignKey(ModelParent, on_delete=models.CASCADE, related_name='childs')
type = models.SmallIntegerField(choices=TYPES, default=0)
目前,只有一个' ModelChild'在数据库中属于唯一的' ModelParent'目前在数据库中,'类型' ' ModelChild'的价值等于' 1',我得到了' ModelParent'对象和我需要汇总他的孩子的数量'类型是' 1'以及他的孩子的数量'其中type是' 2',这就是我尝试这样做的方式:
queryset = ModelParent.objects \
.annotate(first_count=Count('childs', filter=Q(childs__type=1))) \
.annotate(second_count=Count('childs', filter=Q(childs__type=2))).get(pk=1)
查询不会抛出任何错误,但在查看响应时,两个注释的值都是' 1'当它应该是' 1'仅适用于' first_count'和' 0' for' second_count'。
我也注意到,无论我设定的是什么价值,所以' childs__type'在过滤器" filter = Q(childs__type = 1)"中,结果总是相同的,我可以这样设置它,例如:' childs__type = 10'并且计数仍等于' 1' ...就像整个'过滤器' param被忽略了。
答案 0 :(得分:2)
基于this answer我设法以这种方式实现了它,但我需要添加一些内容,例如' output_field'到子查询和' Coalesce'对于注释,< output_field' django要求它,没有它就没有工作,并且' Coalesce'是必需的,因为如果结果为零,默认情况下子查询将返回' null'什么' Coalesce'确实是在结果为null时检索默认值,在这种情况下我将其设置为零:
childs_base_query = ModelChild.objects.filter(parent=OuterRef('pk'))
first_type_query = Subquery(childs_base_query
.filter(type=1)
.values('parent')
.annotate(count=Count('pk'))
.values('count')
, output_field=IntegerField())
second_type_query = Subquery(childs_base_query
.filter(type=2)
.values('parent')
.annotate(count=Count('pk'))
.values('count')
, output_field=IntegerField())
queryset = ModelParent.objects \
.annotate(first_count=Coalesce(first_type_query, 0)) \
.annotate(second_count=Coalesce(second_type_query, 0))
我希望它可以帮助别人。