Как отфильтровать набор запросов на основе булевого значения, а затем подсчитать в шаблоне
Я хочу подсчитать, сколько заданий открыто и сколько закрыто. Я не понимаю, почему это не работает, я добавил {{ap.id}} и {{open.line_num_id }} после цикла forloop, чтобы посмотреть, что получилось. Я бы подумал, что если они совпадают, то они добавляются в счетчик. Это не так, все задания подсчитываются независимо от оператора "if". Совершенно не понимаю, что происходит и почему. Любая помощь будет очень признательна .
У меня есть две модели:
class Airplane(models.Model):
line_num = models.CharField(max_length=10, unique=True)
vh_num = models.CharField(max_length=4, unique=True)
vz_num = models.CharField(max_length=4, unique=True)
stall = models.CharField(max_length=30, choices=stall_picker)
status = models.CharField(max_length=30, choices=status_picker)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
is_completed = models.BooleanField(default=False)
pm = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.line_num
class Job(models.Model):
line_num = models.ForeignKey(
Airplane, on_delete=models.CASCADE, related_name="ap_jobs")
job_num = models.CharField(max_length=10, unique=True)
description = models.CharField(max_length=200)
status = models.CharField(max_length=30, choices=status_picker)
category = models.CharField(max_length=30, choices=categories_picker)
is_completed = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class meta:
ordering = ["category", "status"]
def __str__(self):
return (f"{self.job_num}: {self.description} : {self.is_completed}")
Мое мнение:
def Ap_linup(request):
context = {
'ap_list': Airplane.objects.all().filter(is_completed=False),
'open_jobs': Job.objects.all().filter(is_completed=False),
'closed_jobs': Job.objects.all().filter(is_completed=True)
}
return render(request, 'airplane/airplane_list.html', context)
Шаблон:
{% extends 'base.html' %}
{% block title %} Airplane List {% endblock %}
{% block content %}
<center>
<div class="row">
{% for ap in ap_list %}
<div class="col-md-3">
<div class="card">
<div class="card-body">
<h1>
<center>
<a href="{% url 'airplane:ap_detail' ap.id %}">{{ ap.line_num }}</a>
</center>
</h1>
<h3>
<p>Stall:<strong>{{ ap.stall }}</strong> VH:<strong>{{ ap.vh_num }}</strong> VZ:<strong>{{ap.vz_num }}</strong>
<p>MGR: {{ ap.owner }}</p>
<hr class="lead border border-dark">
<h1>{{ ap.id }}</h1>
{% if ap.status == "Avalible" %}
<p>Current Status:</p>
<p class="text-success">{{ ap.status }}</p>
{% else %}
<p>Current Status:</p>
<p class="text-danger">{{ ap.status }}</p>
{% endif %}
</h3>
<!-- Open Job counts -->
<div>
{% for open in open_jobs %}
{% if open.line_num_id == ap.id %}</p>
<p>Open Jobs: {{ open_jobs.count }}</p>
{% endif %}
{% endfor %}
{% for closed in closed_jobs %}
{% if closed.line_num_id == ap.id %}</p>
<p>Closed Jobs: {{ closed_jobs.count }}</p>
{% endif %}
{% endfor %}
</div>
<div class="lead border border-dark">
{% for comment in ap.ap_comments.all %}
{% if comment_id == ap_id %}
<p><strong>{{ comment.author }}</strong>: {{ comment.text }} @ {{comment.created_at }}</p>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</center>
{% endblock %}
ВЫВОД:
Я хочу отображать количество открытых и закрытых заданий на каждом самолете. Количество открытых и закрытых заданий просто складывается с общим количеством заданий на самолете.
Как упоминает Куско в комментариях, вы можете передать это число в контекст. Это можно сделать следующим образом:
def Ap_linup(request):
context = {
'ap_list': Airplane.objects.all().filter(is_completed=False),
'open_jobs': Job.objects.all().filter(is_completed=False),
'closed_jobs': Job.objects.all().filter(is_completed=True),
'open_jobs_count': Job.objects.filter(is_completed=False).count(),
'closed_jobs_count': Job.objects.filter(is_completed=True).count()
}
Кроме того, вам не нужно .all(), потому что фильтра достаточно.
и если вы хотите еще немного почистить код, чтобы не было много запросов, вы можете объявить переменные перед контекстом.
def Ap_linup(request):
open_jobs = Job.objects.filter(is_completed=False)
closed_jobs = Job.objects.filter(is_completed=True)
context = {
'ap_list': Airplane.objects.all().filter(is_completed=False),
'open_jobs': open_jobs,
'closed_jobs': closed_jobs,
'open_jobs_count': open_jobs.count(),
'closed_jobs_count': closed_jobs.count()
}
return render(request, 'airplane/airplane_list.html', context)