Создание списка на лету в шаблоне Django - PullRequest
9 голосов
/ 15 сентября 2010

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

{% with var1 var2 var3 as some_list %}
    {{ some_list|maximum }}
{% endwith %}

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

В противном случае, я хотел бы знать, как создать тег шаблона, который принимает произвольное количество аргументов.(Я играл с simple_tag, который хорошо работает для тегов, которые принимают фиксированное количество аргументов.)

Я не хочу создавать проблемысинтаксический анализатор и создание подклассов django.template.Node, пока я не выясню, что не существует более простого решения.

Ответы [ 2 ]

15 голосов
/ 15 сентября 2010

Если вы хотите добавить новую переменную (например, some_list), вам потребуется доступ к контексту шаблона, поэтому simple_tag будет недостаточно.

Для меня первый подход состоит в том, чтобы попытаться выполнить такую ​​работу в представлении, чтобы шаблоны были как можно более простыми.

Если это не подходит, вам придется написать тег вручную, например:

@register.tag
def make_list(parser, token):
  bits = list(token.split_contents())
  if len(bits) >= 4 and bits[-2] == "as":
    varname = bits[-1]
    items = bits[1:-2]
    return MakeListNode(items, varname)
  else:
    raise template.TemplateSyntaxError("%r expected format is 'item [item ...] as varname'" % bits[0])

class MakeListNode(template.Node):
  def __init__(self, items, varname):
    self.items = map(template.Variable, items)
    self.varname = varname

  def render(self, context):
    context[self.varname] = [ i.resolve(context) for i in self.items ]
    return ""

И используйте его для создания новой переменной some_list:

{% make_list var1 var2 var3 as some_list %}

Не стесняйтесь назвать его лучше!

3 голосов
/ 15 сентября 2010

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

@register.tag('to_list')
def to_list(_parser, token):
    try:
        parts = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, \
          "%r tag requires at least one argument" % token.contents.split()[0]

    return AsListNode(parts[1:])

class AsListNode(template.Node):
    def __init__(self, parts):
        self.parts = map(lambda p: template.Variable(p), parts)

    def render(self, context):
        resolved = []
        for each in self.parts:
            resolved.append(each.resolve(context))
        return resolved

Шаблон:

<p>{% to_list var1 var2 var3 %}</p>

Обновление

@ Will's решение лучше.Это позволяет сохранить полученный список с помощью другой переменной, чтобы вы могли работать с ним позже.

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