передать список в качестве параметра тегу django - PullRequest
0 голосов
/ 28 августа 2018

У меня есть собственный тег включения в Django, и мне нужно передать туда список в качестве параметра. Что-то вроде этого:

 {% my_tag paramA='asdf' paramB='fdsa' listparams=['X', 'Y'] %}

Это, конечно, не работает, потому что Джанго не знает, как обращаться со списками, переданными таким образом.

Я также могу записать что-то общее, например list_, а затем объединить их в список на стороне сервера:

 {% my_tag paramA='asdf' paramB='fdsa' list_1='X' list_2='Y' list_3='Z' %}

Но мне интересно, есть ли более хороший способ справиться с этим.

1 Ответ

0 голосов
/ 30 августа 2018

Здесь в основном два подхода:

  1. пытается создать список, так или иначе, и передать его my_tag; или
  2. изменить 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 на два списка, но это может быть сложно.

...