Как получить список текущих переменных из шаблона Jinja 2?

Если я верну шаблон Jinja2 следующим образом: return render_response('home.htm', **context)

Как тогда получить список переменных в контексте из шаблона?


person Christian    schedule 03.08.2010    source источник
comment
Как насчет чтения исходного кода шаблона? Что случилось с этим?   -  person S.Lott    schedule 03.08.2010


Ответы (3)


Технически, поскольку контекст не передается как именованный словарь, требуется небольшая работа для создания списка переменных контекста внутри шаблона. Хотя это возможно.

  1. Определите контекстную функцию Jinja, чтобы возвращать jinja2.Context объект, который по сути является словарем глобальных переменных/функций

  2. Сделайте эту функцию доступной в глобальном пространстве имен; то есть глобальный словарь jinja2.Environment или jinja2.Template

  3. При желании отфильтруйте объекты из контекста; например, используйте callable(), чтобы пропустить глобальные вспомогательные функции Jinja по умолчанию (диапазон, объединение и т. д.). Это можно сделать в контекстной функции или в шаблоне; везде, где это имеет смысл.

Пример:

>>> import jinja2
>>> 
>>> @jinja2.contextfunction
... def get_context(c):
...         return c
... 
>>> tmpl = """ 
... {% for key, value in context().items() %}
...     {% if not callable(value) %}
...         {{ key }}:{{ value }}
...     {% endif %}
... {% endfor %}
... """
>>> 
>>> template = jinja2.Template(tmpl)
>>> template.globals['context'] = get_context
>>> template.globals['callable'] = callable
>>>
>>> context = {'a': 1, 'b': 2, 'c': 3}
>>> 
>>> print(template.render(**context))
        a:1
        c:3
        b:2

[В качестве альтернативы вызовите render_response с ('home.htm', context=context), чтобы другое решение заработало.]

person Garrett    schedule 11.08.2010
comment
Обратите внимание, что из-за проверки callable ваше решение будет игнорировать функции, которые явно были переданы как часть контекста. Вероятно, это случается не часто, но может иметь значение. - person Daniel Werner; 21.06.2011
comment
Истинный. Это простое решение определенно можно улучшить. Например, если template является глобальным, get_context() может вернуть новый словарь, основанный на context, но без ключей, которые также существуют в template.globals. - person Garrett; 21.06.2011
comment
Добавлен запрос функции, чтобы включить это по умолчанию github.com/mitsuhiko/jinja2/issues/174 - person anatoly techtonik; 17.01.2013
comment
@techtonik Есть новости? борюсь именно с этим - person Pavel 'Strajk' Dolecek; 23.10.2014
comment
@Strajk, я спросил Армина, но не уверен, что у него есть время на это посмотреть. Для меня запрос на вытягивание со скриншотом был бы более убедительным, чем какой-то кусок кода и какая-то идея, витающая вокруг. - person anatoly techtonik; 24.10.2014

Вот как заставить @crewbum answer работать из приложения Flask:

import jinja2

@jinja2.contextfunction
def get_context(c):
    return c

app.jinja_env.globals['context'] = get_context
app.jinja_env.globals['callable'] = callable
person joemaller    schedule 07.12.2012
comment
Куда ты это положишь? - person johnny; 28.04.2015
comment
В инициализации приложения (или фабрике приложений). Если вы используете какие-либо расширения flask, такие как flask-sqlalchemy, flask-login и т. д., это может быть в том же месте, где они созданы. - person Brian Peterson; 19.11.2015

Я обнаружил, что @Garrett answer немного сложнее, чем я хотел. Я обнаружил, что могу легко проверить контекст, добавив клон контекста в сам контекст:

contextCopy = dict(context)
context['all'] = contextCopy

А затем красиво распечатать это в моем шаблоне Jinja с помощью <pre>{{ all|pprint }}</pre>.

person Jo Sprague    schedule 25.11.2019