Я ненавижу себя за то, что являюсь тем пользователем StackOverflow, который «отвечает» на вопрос, говоря «не делай так, делай так», но ... не делай так, делай так:
Джанго действительно поощряет вас делать такую логику в представлении. Вы "должны" заполнить ваш placement_list
до правильной длины перед отправкой его в ваш шаблон для рендеринга.
Вы сказали, что placement_list
в настоящее время - это набор запросов, определенный в представлении, а затем отправленный как есть в шаблон. Допустим, то, что вы сейчас делаете, выглядит примерно так:
placement_list = MyModel.objects.all()
Что если мы хотим, чтобы это всегда было длиной не менее 50 единиц? Мы можем преобразовать placement_list
из набора запросов в список и добавить фиктивные MyModel
объекты в этот массив.
padded_placements = placement_list + [MyModel()]*(50-len(placement_list))
Обратите внимание, что мы создаем здесь MyModel()
объекты, но на самом деле не делаем create
в стиле Django и / или не сохраняем что-либо в базу данных. Это пустые «фиктивные» объекты, которые мы можем отправить в наш шаблон для использования в качестве заполнителей без загрязнения наших реальных данных.
Давайте сделаем один трюк для только что написанной строки, чтобы упростить создание шаблонов:
padded_placements = placement_list + [MyModel(url='DEFAULT')]*(50-len(placement_list))
Теперь для всех наших фиктивных объектов их атрибут url
будет установлен в строку DEFAULT
. Это не пройдет валидацию URL на уровне объекта, но это не имеет значения, поскольку мы не сохраняем эти макеты в БД - эти валидаторы никогда не будут вызваны.
Отправьте padded_placements
в шаблон и найдите наш пользовательский атрибут:
{% for placement in padded_placements %}
{% if placement.url != 'DEFAULT' %}
<a href="{{ placement.url }}">
<img src="{{ MEDIA_URL }}{{ placement.image }}"/>
</a>
{% else %}
<p>do default stuff</p>
{% endif %}
{% endfor %}
Две ноты:
Вашим фиктивным MyModel
объектам могут потребоваться дополнительные атрибуты в зависимости от того, как эти объекты используются в шаблоне и как ваша модель представляет себя. Например, если ваш метод str / repr использует MyModel.description
, вам нужно будет включить это поле.
Передача списка в шаблон вместо набора запросов означает, что вы потеряете доступ к элементам набора запросов в своем шаблоне. Это замечательно, поскольку любая логика типа набора запросов (фильтрация, exists
проверки и т. Д.), Которую вы действительно выполняете, ДЕЙСТВИТЕЛЬНО должна выполняться в представлении, а не в шаблоне.