【问题标题】:django: how to annotate queryset with count of foreignkey reverse after Trunc?django:如何在 Trunc 之后用外键反向计数注释查询集?
【发布时间】:2020-04-09 23:20:14
【问题描述】:

型号:

class A(models.Model):
    created_on = models.DateTimeField()

class B(models.Model):
    a = models.ForeignKey('A',  verbose_name='bs')

class C(models.Model):
    a = models.ForeignKey('A',  verbose_name='cs')

我想用A来统计B和C的个数,然后分组。

这是我的尝试,但结果不正确。

from django.db.models import  Count, Q
from django.db.models.functions import Trunc

a_qs = A.objects.filter(Q(created_on__gte=start_date, created_on__lte=end_date))
g = a_qs.objects.annotate(time=Trunc('created_on', 'month')).values('time').order_by('time')

result = g.annotate(a_total=Count('id'), b_total=Count('bs'), c_total=Count('cs'))

虽然这样不会报错,但是结果会不正确。我不想循环查询集。

我有个idea可以满足我的需求,但最后还是需要合并queryset。

a_qs = A.objects.filter(Q(created_on__gte=start_date, created_on__lte=end_date))

a_g = a_qs.annotate(time=Trunc('created_on', 'month')).values('time').order_by('time')
a_result = a_g.annotate(a_total=Count('id'))

b_g = B.objects.filter(a__in=a_qs).annotate(time=Trunc('a__created_on', 'month')).values('time').order_by('time')
b_result = b_g.annotate(b_total=Count('id'))

c_g = ...
c_result = ...

【问题讨论】:

    标签: python mysql django django-rest-framework


    【解决方案1】:

    这里的主要问题是您制作了 两个 JOIN,因此 JOIN 充当了彼此的“乘数”。您可以通过以下方式计算 distinct 相关对象:

    A.objects.filter(
        created_on__range=(start_date, end_date)
    ).annotate(
        time=Trunc('created_on', 'month')
    ).values('time').annotate(
        a_total=Count('id', distinct=True),
        b_total=Count('b', distinct=True),
        c_total=Count('c', distinct=True)
    ).order_by('time')

    【讨论】:

    • 也可以在 prefetch_related 或 select_related 模型中完成吗?我试过了,但结果显示没有。有什么提示吗? @威廉
    • @M.A.K.Simanto:这将返回 dictionariesQuerySet,因此 .select_related.prefetch_related 都没有多大意义。如果您在没有截断的情况下执行此操作,则这些组将是单独的 A 对象,所以不会。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 2020-07-18
    • 2011-09-23
    • 1970-01-01
    • 2019-02-28
    • 2019-11-24
    相关资源
    最近更新 更多