【问题标题】:How to make a query in Django that counts foreign key objects?如何在 Django 中进行计算外键对象的查询?
【发布时间】:2022-01-08 12:26:44
【问题描述】:

大家好!

Django 中的新手,很困惑,感谢帮助!我正在尝试创建一个表,例如:

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

如何进行复杂查询,从 Appeal 模型中检索信息?并放置到上表的确切字段?:(

【问题讨论】:

    标签: python-3.x django django-models django-views foreign-keys


    【解决方案1】:

    您可以通过以下方式查询:

    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>{{ organization.total }}</td><td>{{ organization.total_written }}</td><td>{{ organization.total_oral }}</td></tr>
    {% endfor %}
    </tbody>
    </table>

    【讨论】:

      【解决方案2】:

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

      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>
      

      【讨论】:

      • Thnx Arash 再次,它确实是有效的解决方案!尊重!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      相关资源
      最近更新 更多