Django для... пустого с другим контейнером, когда он пуст

У меня есть общий шаблон, в котором у меня есть контейнер в HTML (например, ul, table ...) с элементами из кверисета. Однако, когда список пуст, я не хочу отображать сам контейнер.

Я стремлюсь получить эквивалент

{% if query.exists %}
  <ul class="list-of-stuff">
    {% for x in query %}
      <li>{{ x }}</li>
    {% endfor %}
  </ul>
{% else %}
  <p class="information">
    The list is empty.
  </p>
{% endif %}

но без дополнительного запроса (query.exists), подобно тому, как это делает for...empty. Однако один большой недостаток for...empty заключается в том, что я не могу удалить или изменить контейнер, когда список пуст.

Как я могу получить эквивалент вышесказанного только при одном выполнении запроса чистым способом (т.е. без отображения тега контейнера if forloop.first и тому подобного)? Я открыт для внедрения новых тегов или фильтров или использования легковесной библиотеки с ними.

Вы можете проверить истинность самого query, это загрузит данные в память, так что тогда это будет только однократный запрос. Таким образом, мы проверяем {% if query %}, а не {% if query.exists %}:

{% if query %}
  <ul class="list-of-stuff">
    {% for x in query %}
      <li>{{ x }}</li>
    {% endfor %}
  </ul>
{% else %}
  <p class="information">
    The list is empty.
  </p>
{% endif %}

И действительно, QuerySet имеет истинность True, если содержит хотя бы один элемент . Таким образом, он выполнит запрос и загрузит данные в память. Если записей нет, то {% if query %} не сработает, и таким образом мы получим, что список пуст. Если есть хотя бы одна строка, то {% if query %} успешна, и тогда нам не придется делать дополнительный запрос для перечисления query.

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