1👍
✅
You can’t perform complex logic like you want in the template language. I like that fact because it helps prevent you from introducing business logic into the template (where it doesn’t belong).
You should be able to accomplish what you want with the following:
from django.db.models import Count
class Screening(generic.DetailView):
model = Job
template_name = 'dashboard/screening.html'
def get_context_data(self, **kwargs):
context = super(Screening, self).get_context_data(**kwargs)
# Fetch the sender_id for each unread message.
# Count the number of times that the sender_id was included.
# Then convert the list of tuples into a dictionary for quick lookup.
sent_messages = dict(self.request.user.received_messages.filter(
read_at__isnull=True
).values('sender_id').annotate(
messages_sent=Count('user_id')
).values_list('sender_id', 'messages_sent'))
candidates = []
for candidate in self.object.applied_to.all().order_by('candidate'):
candidate.messages_sent = sent_messages.get(candidate.id, 0)
candidates.append(candidate)
context['candidate_list'] = candidates
return context
Then in your template you’d use:
{% for candidate in candidate_list %}
{{ candidate.get_full_name }}
{{ candidate.candidate.city }}
{{ candidate.messages_sent }}
{% endfor %}
The downside to this approach is that you wouldn’t have access to the individual messages.
Edit: You can read about annotations and aggregations here. There’s a lot more information there.
Source:stackexchange.com