我希望在我的应用程序中使用某种设计模式,但我不确定我的模式是否真的适合Flask机制。我只是在核实我没有忽视现有的解决方案。
我希望有一个顶级视图,用于呈现另一个代理请求的响应。问题是,我不是代理外部URL,而是代理同一个应用程序中的视图(类似于依赖于其他蓝图的蓝图)。与'render_template()'函数类似,我正在寻找像render_view
,甚至更好,*request_view_as_string*
的东西。然后我需要处理响应并重新渲染。
我尽可能使用模板继承(jinja2),但我的很多困难来自于模板块之间的大量非模板处理。我仍然感觉到了jinja,我的模板开始感觉被黑客污染了。
基本上,我误解了jinja的角色。我的应用程序需要在jinja上加重。我一直试图尽快进出jinja,这就是我的嵌套依赖开始引起问题的地方。最终,我的“子视图”所需的大多数功能都是内置于Jinja中的,我只是不确定如何将它们与FLask正确集成。
答案 0 :(得分: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测试,根据用户帐户启用的内容加载不同功能等),extends
,include
和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)
最后,您可以将返回字符串的callables传递给任何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)
答案 1 :(得分:0)
我认为Sean的第一个答案是最合适的,但是当Jinja使Python任务有点困难的时候,我确实碰到了这个小机制。
http://werkzeug.pocoo.org/docs/local/
这应该比Flask的g变量更有效率。另请参见略有不同的用法(当一个全局“命名空间”不再可管理时)
http://flask.pocoo.org/snippets/13/
我经常忘记Flask和Werkzeug是相关的项目。这样做的巨大好处是它们的大部分功能都与其他项目不重叠。
当你从Flask那边接近新手时,如果你觉得Flask缺少一些齿轮,那很有可能是因为他们已经将它们包含在Werkzeug中了。