3

我希望在我的应用程序中使用某种设计模式,但我不确定我的模式是否真的适合 Flask 机制。我只是在验证我没有忽略现有的解决方案。

我想要一个顶级视图来呈现另一个代理请求的响应。问题是,我不是代理外部 URL,而是代理来自我的同一个应用程序中的视图(有点像依赖于其他蓝图的蓝图)。类似于 'render_template()' 函数,我正在寻找类似render_view,甚至更好的东西*request_view_as_string*。然后我需要处理响应并重新渲染。

我正在尽我所能使用模板继承(jinja2),但我的大部分困难来自模板块之间的大量非模板处理。我仍然对 jinja 有感觉,而且我的模板开始被黑客污染。


编辑

基本上,我误解了神社的作用。我的应用程序需要在 jinja 上构建更重的内容。我一直在尝试尽快进出 jinja,这就是我的嵌套依赖项开始导致问题的地方。最终,我的“子视图”所需的大部分功能都内置在 Jinja 中,我只是不确定如何正确地将它们与 Flask 集成。

4

2 回答 2

2

首先,Jinja2 支持macros,它可以让你在模板之间共享功能:

{# helpers.jinja #}
{% macro generate_select(itrbl) %}
    <select{{kwargs|xmlattrs}}>
    {% for item in itrbl %}
        <option value="{{item.value}}">{{item.text}}</option>
    {% endfor %}
    </select>
{% endmacro %}

{# page1.jinja #}
{% import "helpers.jinja" as helpers %}
{{ helpers.generate_select(data, name="my_data_field") }}

对于更复杂的功能(A / B 测试,根据用户帐户启用的功能加载不同的功能等)extendsinclude, 和import可以采用可变值:

{# A custom template with a *lot* of hooks #}
{% extends base_template %}
{% import custom_functionality_provider as provider %}
{% block common_name %}
    {% if features.feature_x %}
        {% include feature_x_include %}
    {% endif %}
    {{ provider.operation() }}
{% endblock common_name %}

@app.route("/some-route")
def some_route():
    # Of course, in real life you would determine these values
    # on the basis of user / condition lookups, rather than
    # hardcoding values in your render_template call
    render_template("custom.jinja", base_template="AB/A/base.jinja",
        custom_functionality_provider="macros/lowcostplan.jinja",
        feature_x_include="AB/A/features/feature_x.jinja",
        features=some_features_object)

最后,您可以将返回字符串的可调用对象传递给任何 Jinja 模板,从而获得 Python 的全部功能:

def custom_implimentation_a(**context_args):
    return render_template("template_a.jinja", **context_args)

def custom_implimentation_b(**context_args):
    return render_template("template_b.jinja", **context_args)

@app.route("/some-route")
def some_route():
    if condition:
        provider = custom_implimentation_a  # Note, no parenthesis
    else:
        provider = custom_implimentation_b

    return render_template("some_page.jinja", provider=provider)
于 2013-07-10T05:42:19.270 回答
0

我确实认为 Sean 的第一个答案是最合适的,但是当 Jinja 使 Python 任务变得有点困难时,我确实遇到了这个小机制。

http://werkzeug.pocoo.org/docs/local/

这应该比 Flask 的 g 变量更有效率。另请参阅略有不同的用法(当一个全局“命名空间”不再可管理时)

http://flask.pocoo.org/snippets/13/

我经常忘记 Flask 和 Werkzeug 是相关的项目。这样做的巨大好处是它们的大部分功能不会与其他项目重叠。

当您是从 Flask 方面接近的新手时,如果您觉得 Flask 缺少一些齿轮,很有可能是因为他们已经将它们包含在 Werkzeug 中。

于 2013-07-20T03:21:46.750 回答