如何在 Django 中进行计算外键对象的查询?

How to make a query in Django that counts foreign key objects?

大家好!

Django新手,一头雾水,不胜感激!我正在尝试创建一个 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

拥有三个模型:

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 的确切字段?:(

您可以查询:

from django.db.models import Count, Q

organizations = Organization.objects.annotate(
).annotate(
    total=Count('appeal'),
    total_written=Count('appeal', filter=Q(appeal__appeal_form__form_name='in written form')),
    total_oral=Count('appeal', filter=Q('appeal__appeal_form__form_name='in oral form'))
)

然后我们可以渲染 Organizations:

<table>
<thead>
  <tr><th>Organization</th><th>Total amount of appeals</th><th>Amount of written form appeals</th><th>Amount of oral form appeals</th></tr>
</thead>
<tbody>
{% for organization in organizations %}
  <tr><td>{{ organization.organization_name }}</td><td>{{ <strong>organization.total</strong> }}</td><td>{{ <strong>organization.total_written</strong> }}</td><td>{{ <strong>organization.total_oral</strong> }}</td></tr>
{% endfor %}
</tbody>
</table>

我知道我的解决方案不是最好的。但结果正是您要找的。

views.py:

from django.shortcuts import render
from .models import Appeal, Organization
from django.db.models import Count


def index(request):
    on = Organization.objects.values_list('organization_name').distinct()
    x = Appeal.objects.values(
        "organization__organization_name", "appeal_form__form_name"
    ).annotate(total=Count("appeal_form__form_name"))
    
    out = {}
    for name in on:
        out[name[0]] = {}
    for el in x:
        for k in out.keys():
            if not out[k].get('total'):
                out[k]['total'] = 0 
            if el.get('organization__organization_name') == k:
                out[k].update({el.get('appeal_form__form_name'):el.get('total')})
                out[k]['total']+=el.get('total')
    context = {
        "appeal": out,
    }
    return render(request, "pages/index.html", context)

index.html:

<table>
    <tr>
        <th>Organization</th>
        <th>Appeal Form</th>
        <th>Total amount of appeals </th>
        <th>Amount of written form appeals</th>
        <th>Amount of oral form appeals</th>
    </tr>
{% for k,v in appeal.items %} 
<tr>
    <td> {{ k }} </td>
    {% for form_name ,form_count in v.items %}
    <td align="center">{{ form_count}}</td> 
    {% endfor %} 
</tr> 
{% endfor %}
</table>