【问题标题】:Django view filter countDjango查看过滤器计数
【发布时间】:2021-09-19 16:53:50
【问题描述】:

我想了解每个“客户”(Cliente) 的“任务”(Pendentes) 数量

我的 models.py 中有这个模型:

class Cliente(models.Model):
    id = models.IntegerField(primary_key=True)
    nome = models.CharField(max_length=200, help_text="Nome")
    localidade = models.CharField(max_length=100, help_text="Localidade")
    [...]

class Pendente(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text="ID Unico")
    cliente = models.ForeignKey('Cliente', on_delete=models.RESTRICT, blank=True, null=True)
    memo = models.TextField(null=True, blank=True, help_text="Memória Descritiva", max_length=200)
    criado = models.DateField(default=date.today, null=True, blank=True, help_text="Data registo ")
    concluir = models.DateField(null=True, blank=True, help_text="Data de execução máxima ")
    tecnico = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    tecnicoatribuido = models.ForeignKey('TecnicoAtribuido', on_delete=models.SET_NULL, blank=True, null=True)

基本上我想运行这个sql:

"select A.id, A.nome, A.localidade, count(B.id) as tarefas
from todolist_pendente B 
LEFT JOIN todolist_cliente A
ON A.id = B.cliente_id
GROUP by A.id;"

似乎无法弄清楚它如何在视图上工作。

我可以通过以下方式获得每个客户的计数:

resultado = Pendente.objects.values('cliente').order_by('cliente').annotate(count=Count('id'))

但这不会在模板上呈现每个客户的姓名。

在我正在使用的模板上:

  <ul>
    {% for obj in resultado %}
    <li>{{ obj.cliente}} : {{ obj.count}}</li>
    {% endfor %}
  </ul>

这是渲染:

6 : 2
35 : 1
40 : 1
92 : 1
106 : 1
105 : 1

有没有办法获取外键值'nome',以便它可以像这样呈现:

id  Nome    Localidade  Tarefas
6   Cliente A   Quarteira   2
35  Cliente B   Lisboa  1
40  Cliente C   Barreiro    1
92  Cliente D   Lisboa  1
105 Cliente E   Faro    1
106 Cliente F   Barreiro    1

我们将不胜感激...

【问题讨论】:

    标签: django django-views


    【解决方案1】:

    你可以试试这个方法:

    class Cliente(models.Model):
        id = models.IntegerField(primary_key=True)
        nome = models.CharField(max_length=200, help_text="Nome")
        localidade = models.CharField(max_length=100, help_text="Localidade")
        [...]
    
        @property
        def pendente_count(self):
          return Pendente.objects.filter(cliente=self).count()
    
    
    # from client object now you can access pendente_count property
    
    # If you pass client queryset context with your template
    queryset = Cliente.objects.all()
    
    # inside template
    {% for client in queryset %}
      {{ client.nome }}  {{ client.pendente_count }}
    {% endfor %}
    
    
    # or you can use this without adding a new property in you model
    {{ client.pendente_set.all.count }}
    

    【讨论】:

      【解决方案2】:

      感谢您的帮助! 用它修复了以下内容:

      views.py:

      resultado = Cliente.objects.annotate(pendente_count=Count('pendente')
      

      模板(只想要有 Pendentes 的客户,所以我添加了一个 if 子句):

          <tbody>
        {% for cliente in resultado3 %} {% if cliente.pendente_count > 0 %}
        <tr>
          <td>{{ cliente.id }}</td>
          <td>{{ cliente.nome }}</td>
          <td>{{ cliente.localidade }}</td>
          <td>{{ cliente.pendente_count }}</td>
        </tr>
        {% endif %} {% endfor %}
      </tbody>
      

      谢谢! 我感觉自己就像一只井上的仓鼠 :)

      【讨论】:

      • 我建议在视图中进行过滤,而不是在模板中进行过滤,因为通过在模板中进行过滤,您将检索到 Clients,然后您只需将其过滤掉。通常最好用查询尽可能多地过滤掉。
      • 您好 Willem,我同意,我最终更改了 qs 以包含过滤器。
      【解决方案3】:

      您可以使用相关Pendente 的数量来注释每个Cliente

      from django.db.models import Count
      
      resultado = Cliente.objects.annotate(
          pendente_count=Count('pendente')
      )

      您还可以过滤Clients,这样它们至少应该有一个 Pendente:

      from django.db.models import Count
      
      resultado = Cliente.objects.annotate(
          pendente_count=Count('pendente')
      ).filter(pendente_count__gt=0)

      这将使用 one 查询访问数据库,从而让数据库计算 相关 Pendente 的数量,每个 Cliente

      然后在您的模板中,您可以使用:

      <table>
        <thead>
          <tr>
            <th>id</th><th>Nome</th><th>Localidade</th><th>Tarefas</th>
          </tr>
        </thead>
        <tbody>
          {% for cliente in resultado %}
              <tr><td>{{ cliente.id }}</td><td>{{ cliente.nome }}</td><td>{{ cliente.localidade }}</td><td>{{ cliente.pendente_count }}</td></tr>
          {% endfor %}
        </tbody>
      </tble>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-08
        • 1970-01-01
        相关资源
        最近更新 更多