Как подсчитать объекты внешнего ключа с помощью аннотации в 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

Объекты модели Appeal:

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

Я пытаюсь создать таблицу в шаблоне, например:

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

Содержимое таблицы должно быть получено из модели Appeal, которая отображается в шаблоне.

Вопрос: Как выглядит запрос в views.py с использованием модели Appeal?

я рекомендую вам прочитать о том, как делать сложные запросы в django из этого раздела documents. Вот как будет выглядеть ваш запрос:

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, 'письменная_сумма': 1, 'устная_сумма': 2}, {'организация': 'Организация 2', 'total_appeals': 2, 'письменная_сумма': 1, 'oral_amount': 1}]

Объяснения:

  • значения для группировки по organization
  • Count для подсчета форм в этой организационной группе
  • мы используем Case для добавления if condition, then=1 для возврата значения (иначе возвращается null)
  • сумма_записи должна быть целой, поэтому мы устанавливаем ее в 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

Вернуться на верх