#django #django-views
Вопрос:
Я хочу узнать количество «задач» (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.объекты.значения(‘cliente’).order_by(‘cliente’).аннотировать(количество=Количество(‘идентификатор’))
Но это не отображает имя каждого клиента в шаблоне.
В моем шаблоне, который я использую :
<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
есть ли способ получить значение внешнего ключа «ном», чтобы его можно было отобразить следующим образом:
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
Помощь была бы признательна…
Ответ №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>
Спасибо!
Я чувствовал себя Хомяком на колодце 🙂
Комментарии:
1. Я бы посоветовал фильтровать в представлении, а не в шаблоне, так как, фильтруя в шаблоне, вы получите
Client
s, которые затем просто отфильтруете. Обычно лучше отфильтровать как можно больше с помощью запроса.2. Привет, Виллем, я согласен, и в итоге я изменил qs, чтобы включить фильтр.
Ответ №3:
Вы можете аннотировать каждый Cliente
из них количеством связанных с Pendente
:
from django.db.models import Count
resultado = Cliente.objects.annotate(
pendente_count=Count('pendente')
)
вы также можете отфильтровать Client
буквы s, чтобы они, по крайней мере, имели одну Pendente
:
from django.db.models import Count
resultado = Cliente.objects.annotate(
pendente_count=Count('pendente')
).filter(pendente_count__gt=0)
Это приведет к попаданию в базу данных с помощью одного запроса и, таким образом, позволит базе данных подсчитать количество связанных 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>