Как визуализировать только данный блок, используя Jinja2 с Flask и Pjax

Я ищу удобный способ визуализации частичных шаблонов с использованием Flask и Pjax. Я придумал что-то вроде этого:

# utils.py
def render_pjax(base, view, **kwargs):
    is_pijax = "X-PJAX" in flask.request.headers
    return flask.render_template(
        'pjax_wrapper.html', is_pjax=is_pijax, extends=base, view=view, **kwargs)

# pjax_wrapper.html
{% if not is_pjax %}

    {% extends extends %}
    {% block pjax_content %}
        {% include view %}
    {% endblock %}

{% else %}

    {% include view %}

{% endif %}

Таким образом, я могу определить шаблоны следующим образом:

# without_pjax.html
<div>
    <h1>Search</h1>
    (...some static content..)
    <div class="content" id="search-results">
        {% block pjax_content %}

        {% endblock %}
    </div>
</div>

# with_pjax.html
<ul>
    <li>entry1</li>
    <li>entry2</li>
    ...
    <li>entry2</li>
</ul>

И используйте все это так:

# usage
@app.route('/')
def pjax_view():
    return render_pjax('without_pjax.html', 'with_pjax.html', context=...)

Мое решение довольно удобно, нет места, где дублируется код, но все же мне нужно использовать два шаблона для каждого pjax-совместимого представления. Я пытался найти лучший путь, желательно такой же, как в этой библиотеке для Django: DjPj. Это позволяет указать, какой блок мы хотим визуализировать в ответ на запрос pjax. Я пытался сделать то же самое в Flask, но безуспешно.

Я был бы очень признателен за помощь в решении этой проблемы. Можете ли вы имитировать поведение DjPj в Flask + Jinja2, или, может быть, есть другие красивые решения, которые я просто не могу найти?

1 ответ

Решение

Хорошо, наконец, я создал эту функцию

def pjax(template, pjax_block='pjax_content', **kwargs):
    if "X-PJAX" in flask.request.headers:
        app = flask.current_app
        app.update_template_context(kwargs)
        template = app.jinja_env.get_template(template)
        block = template.blocks[pjax_block]
        context = template.new_context(kwargs)
        return u''.join(block(context))
    else:
        return flask.render_template(template, **kwargs)

Он отображает только данный блок из шаблона, если присутствует заголовок pjax, в противном случае - весь шаблон. Надеюсь, поможет.

Другие вопросы по тегам