如何计算 Django 中带注释的外键对象?

How to count foreign key objects with annotation in Django?

大家好!

Django 新手,困惑中,不胜感激!

拥有三个模型:

class Organization(models.Model):
    organization_name = models.CharField(max_length=50)


class AppealForm(models.Model):
    form_name = models.CharField(max_length=50)


class Appeal(models.Model):
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
    appeal_form = models.ForeignKey(AppealForm, on_delete=models.CASCADE)
    applicant_name = models.CharField(max_length=150)

组织模型的对象:

organization_name
Organization 1
Organization 2

AppealForm 模型的对象:

form_name
In written form
In oral form

上诉对象模型:

organization appeal_form applicant_name
Organization 1 In written form First and Last name
Organization 1 In oral form First and Last name
Organization 1 In oral form First and Last name
Organization 2 In written form First and Last name
Organization 2 In oral form First and Last name

我正在尝试在模板中创建一个 table,例如:

Organization Total amount of appeals Amount of written form appeals Amount of oral form appeals
Organization 1 3 1 2
Organization 2 2 1 1

必须从上诉模型中检索 table 内容中的内容,然后呈现给模板。

问题: 使用上诉模型的 views.py 中的查询是什么样的?

我建议您从 documents 部分阅读有关如何在 Django 中执行复杂查询的信息。 您的查询如下:

from django.db.models import Count, Case, When, IntegerField

Appeal.objects
      .values('organization')
      .annotate(
          total_appeals=Count('appeal_form'), 
          written_amount=Count(Case(
                When(appeal_form__form_name="In written form", then=1),
                output_field=IntegerField(),
          )),
          oral_amount=Count(Case(
                When(appeal_form__form_name="In oral form", then=1),
                output_field=IntegerField(),
          )),
       ).order_by()

将上述查询设置为一个值并遍历它并查看结果。你应该得到这样的东西

[{'organization': 'Organization 1', 'total_appeals': 3, 'written_amount': 1, 'oral_amount': 2}, {'organization': 'Organization 2', 'total_appeals': 2, 'written_amount': 1, 'oral_amount': 1}]

解释:

  • 要按 organization
  • 分组的值
  • Count 统计该组织组中的表格
  • 我们使用 Case 添加一个 if condition,然后 =1 到 return 值(否则 return null)
  • written_amount 需要是整数所以我们在 output_field
  • 中设置它

文档中的条件部分https://docs.djangoproject.com/en/dev/ref/models/conditional-expressions

为什么应该使用 order_by() 来对查询进行分组 https://docs.djangoproject.com/en/4.0/topics/db/aggregation/#interaction-with-order-by