Шаблон Django - Проблемы с доступом к дочерним моделям / запуском условных тестов
Я пытаюсь запустить условный тест в шаблоне Django, основанный на подсчете дочерних объектов.
Я передал в шаблон переменную под названием "productcodes" и могу успешно перебирать каждый элемент в ней.
Модели
class Productcode(models.Model):
product_code = models.CharField(max_length=50)
def __str__(self):
return self.product_code
class Test(models.Model):
worksorder = models.ForeignKey(Worksorder, blank=True, null=True, on_delete=models.CASCADE,)
productcode = models.ForeignKey(Productcode, blank=True, null=True,on_delete=models.CASCADE)
tester = models.ForeignKey(Tester, blank=True, null=True,on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True, blank=True)
def __str__(self):
return self.date
{% if productcodes %}
{% for code in productcodes %}
<tr>
<th scope="row"><a href="show_productcode/{{ code.id }}"> {{ code }} </a></th>
{% if code.test_set.all.count < 1 %}
<td> 0 </td>
{% elif %}
<td>{{ code.test_set.all.count }}</td>
{% endif %}
<td>Future Dev WO</td>
</tr>
{% endfor %}
{% endif %}
Проблема, с которой я столкнулся, заключается в том, что оператор if не работает с ошибкой:
Неожиданный конец выражения в теге if.
{% if code.test_set.all.count < 1 %}
Я проверил выражение в оболочке, я упустил что-то очевидное?
С наилучшими пожеланиями
Колин.
Я ожидаю, что в таблице будет выведен подсчет дочерних объектов.
Хотя это и не проблема, я бы посоветовал не считать количество элементов через связанное имя: это приведет к N+1 проблеме, где для N элементов вы сделаете N+1 запросов: один для получения Productcode
элементов, а затем один на Productcode
для получения связанных Test
элементов.
Мы можем усилить это, аннотировав это в представлении, так:
from django.db.models import Count
from django.shorcuts import render
def some_view(request):
productcodes = Productcode.objects.annotate(ntests=Count('test'))
return render(request, 'some-template.html', {'productcodes': productcodes})
Тогда мы можем работать с:
{% for code in productcodes %}
<tr>
<th scope="row"><a href="show_productcode/{{ code.id }}"> {{ code }} </a></th>
{% if code.ntests < 1 %}
<td> 0 </td>
{% elif %}
<td>{{ code.ntests }}</td>
{% endif %}
<td>Future Dev WO</td>
</tr>
{% endfor %}
Вы также можете работать с:
{% for code in productcodes %}
<tr>
<th scope="row"><a href="show_productcode/{{ code.id }}"> {{ code }} </a></th>
{% if not code.ntests %}
<td> 0 </td>
{% elif %}
<td>{{ code.ntests }}</td>
{% endif %}
<td>Future Dev WO</td>
</tr>
{% endfor %}
Вероятно, также лучше использовать {% url … %}
[Django-doc] для генерации пути на основе имени представления вместе с параметрами.