Здесь в основном два подхода:
- пытается создать список, так или иначе, и передать его
my_tag
; или
- изменить
my_tag
так, чтобы проходить список было удобнее.
Построение списков
Шаблоны Django предлагают способы построения списка, хотя большинство из них довольно ограничены.
Использование фильтра шаблона make_list
Например, в Django представлен шаблонный фильтр make_list
[Django-doc] , который принимает итерацию и преобразует ее в список элементов. Например, мы можем использовать фильтр шаблона с:
{% my_tag paramA='asdf' paramB='fdsa' listparams=<b>'XY'|make_list</b> %}
Но есть две потенциальные проблемы с этим: (1) для строки, в которой она проходит по символам, поэтому все элементы будут представлять собой строки из 1 символа, и (2) вы не можете создавать списки, содержащие целые числа и т. Д. если у вас уже нет объекта, подобного коллекции, но это в основном сделает make_list
бесполезным.
Использование .split()
Мы можем решить проблему, заключающуюся в том, что она принимает только 1-символьные строки, выполнив вызов .split()
, это работает только для строк (если тип переменной также не поддерживает функцию .split()
), поэтому мы можем решить проблему с деталями mulit-char с помощью:
{% my_tag paramA='asdf' paramB='fdsa' listparams=<b>'XY Z'.split</b> %}
Реализация собственного тега variadic для создания списков
Мы также можем определить переменный тег, который сначала создает список. Мы делаем это путем реализации пользовательского тега:
# app/templatetags/create_list.py
from django import template
register = template.Library()
@register.simple_tag
def create_list(*args):
return args
Затем мы можем использовать два шага для передачи списка:
{% load <b>create_list</b> %}
{% create_list 'X' 'Y' as <B>mylist</b> %}
{% my_tag paramA='asdf' paramB='fdsa' listparams=<b>mylist</b> %}
Изменение my_tag
Возможно, самым простым способом было бы использовать позиционные параметры здесь для получения списка. Функция в Python имеет два типа параметров: позиционные единицы (переданные без имени параметра) и именованные (те с key=...
).
Таким образом, мы можем использовать позиционные здесь для списка и, таким образом, вызвать тег с помощью:
{% my_tag <b>'X' 'Y'</b> paramA='asdf' paramB='fdsa' %}
В случае, если мы не упоминаем какие-либо позиционные параметры, список считается пустым. Мы можем передать произвольное количество параметров.
Мы можем, например, реализовать тег как:
# app/templatetags/my_tag.py
from django import template
register = template.Library()
@register.simple_tag
def my_tag(<b>*listparams</b>, paramA=None, paramB=None):
# ... processing
return None
Потенциальная проблема этого подхода заключается в том, что мы можем выполнить этот «трюк» только один раз, в том смысле, что мы не можем определить два отдельных таких *arg
s. Конечно, мы можем стремиться разбить *args
на два списка, но это может быть сложно.