Django annotate(...) 获取字典

问题描述 投票:0回答:1

我有一些复杂的 django 查询,其中有很多 .annotate:

query = ModuleEngagement.objects.filter(course_id=course_id)\
            .values('username')\
            .annotate(
                videos_overall=Sum(Case(When(entity_type='video', then='count'), output_field=IntegerField()))) \
            .annotate(
                videos_last_week=Sum(Case(When(entity_type='video', created__gt=seven_days_ago, then=1),
                                          output_field=IntegerField()))) \
            .annotate(
                problems_overall=Sum(Case(When(entity_type='problem', then='count'), output_field=IntegerField()))) \
            .annotate(
                problems_last_week=Sum(Case(When(entity_type='problem', created__gt=seven_days_ago, then='count'),
                                            output_field=IntegerField()))) \
            .annotate(
                correct_problems_overall=Sum(Case(When(entity_type='problem', event='completed', then='count'),
                                                  output_field=IntegerField()))) \
            .annotate(
                correct_problems_last_week=Sum(Case(When(entity_type='problem', event='completed',
                                                         created__gt=seven_days_ago, then='count'),
                                                    output_field=IntegerField()))) \
            .annotate(
                problems_attempts_overall=Sum(Case(When(entity_type='problem', event='attempted', then='count'),
                                                   output_field=IntegerField()))) \
            .annotate(
                problems_attempts_last_week=Sum(Case(When(entity_type='problem', event='attempted',
                                                          created__gt=seven_days_ago, then='count'),
                                                     output_field=IntegerField()))) \
            .annotate(
                forum_posts_overall=Sum(Case(When(entity_type='discussion', then='count'),
                                             output_field=IntegerField()))) \
            .annotate(
                forum_posts_last_week=Sum(Case(When(entity_type='discussion', created__gt=seven_days_ago, then='count'),
                                               output_field=IntegerField()))) \
            .annotate(
                date_last_active=Max('created'))

annotate 是否接受字典作为参数,以便我可以将所有注释移入其中?如果是这样,语法是什么?

django django-orm django-annotate
1个回答
8
投票

annotate 是否接受字典作为参数,以便我可以将所有注释移入其中?如果是这样,语法是什么?

您可以执行字典解包。所以如果你有一本像这样的字典:

my_dict = {
    'total_likes': Sum('likes'),
    'total_articles': Sum('articles'),
}

您可以进行以下查询:

MyModel.objects.annotate(**my_dict)

这相当于:

MyModel.objects.annotate(total_likes=Sum('likes'), total_articles=Sum('articles'))

如果您使用 或更新版本,那么您可以使用以下方法显着简化注释:

ModuleEngagement.objects.filter(course_id=course_id).values('username').annotate(
    videos_overall=Count('pk', filter=Q(entity_type='video')),
    videos_last_week=Count('pk', filter=Q(entity_type='video', created__gt=seven_days_ago)),
    problems_overall=Count('pk', filter=Q(entity_type='problem'),
    problems_last_week=Count('pk', filter=Q(entity_type='problem', created__gt=seven_days_ago)),
    correct_problems_overall=Count('pk', filter=Q(entity_type='problem', event='completed'),
    correct_problems_last_week=Count('pk', filter=Q(entity_type='problem', event='completed', created__gt=seven_days_ago)),
    problems_attempts_overall=Count('pk', filter=Q(entity_type='problem', event='attempted'),
    problems_attempts_last_week=Count('pk', filter=Q(entity_type='problem', event='attempted', created__gt=seven_days_ago)),
    forum_posts__overall=Count('pk', filter=Q(entity_type='discussion'),
    forum_posts__last_week=Count('pk', filter=Q(entity_type='discussion', event='attempted', created__gt=seven_days_ago)),
    date_last_active=Max('created')
).order_by('username')
© www.soinside.com 2019 - 2024. All rights reserved.