Математические операции в шаблонах - PullRequest
0 голосов
/ 04 ноября 2018

В макете у меня есть предопределенное количество мест / пробелов.

Я хочу заполнить это изображениями, но бывают случаи, когда изображение отсутствует или меньше:

Если изображений достаточно, можно использовать следующий код:

{% for placement in placement_list %}
        <a href="{{ placement.url }}">
            <img src="{{ MEDIA_URL }}{{ placement.image }}"/>
        </a>
 {% endfor %}

Но когда в макете ноль или меньше изображений, чем доступно, я хочу показать изображение по умолчанию /

Я знаю, что длину можно проверить с помощью {{place_list | length}}

Я хочу что-то вроде:

 for i to (MAX_NR_placements - {{ placement_list|length }})
       <img src="default" />

1 Ответ

0 голосов
/ 04 ноября 2018

Я ненавижу себя за то, что являюсь тем пользователем 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 проверки и т. Д.), Которую вы действительно выполняете, ДЕЙСТВИТЕЛЬНО должна выполняться в представлении, а не в шаблоне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...