Шаблон 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] для генерации пути на основе имени представления вместе с параметрами.

Вернуться на верх