Подсчет фильтров представления Django
Я хочу узнать количество "задач" (Pendentes) для каждого "клиента" (Cliente)
У меня есть эти модели в моем 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
есть ли способ получить значение foreignkey '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
Помощь будет признательна...
Вы можете попробовать такой подход:
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 }}
Вы можете аннотировать каждый Cliente
количеством связанных Pendente
с:
from django.db.models import Count
resultado = Cliente.objects.annotate(
pendente_count=Count('pendente')
)
Это поразит базу данных одним запросом, и таким образом позволит базе данных подсчитать количество связанных 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>
Спасибо за помощь! Исправил это следующим образом:
views.py :
resultado = Cliente.objects.annotate(pendente_count=Count('pendente')
Шаблон (нужны только те клиенты, у которых есть подвески, поэтому я добавил условие 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>
Спасибо! Я чувствовал себя как хомяк на колодце :)