Python 如何从烧瓶装饰器向Jinja模板发送变量?

Python 如何从烧瓶装饰器向Jinja模板发送变量?,python,templates,flask,decorator,jinja2,Python,Templates,Flask,Decorator,Jinja2,围绕我的BlueprintedFlask应用程序的许多路线都需要向jinja发送“侧栏数据” 我正在寻找最有效的方法。它们必须比将我的“generate_sidebar_data()”函数导入每个蓝图更好,反复说: var1, var2, var3 = generate_sidebar_data() 然后将其与“渲染模板”一起发送: return render_template('template.html', var1=var1,

围绕我的BlueprintedFlask应用程序的许多路线都需要向jinja发送“侧栏数据”

我正在寻找最有效的方法。它们必须比将我的“generate_sidebar_data()”函数导入每个蓝图更好,反复说:

var1, var2, var3 = generate_sidebar_data()
然后将其与“渲染模板”一起发送:

return render_template('template.html',
                           var1=var1,
                           var2=var2,
                           var3=var3
                      )
我想要的是一个装饰器,我可以把它和上面做的事情放在一起(运行函数并将变量发送到jinja),但是我不知道这是否可行。如何从decorator函数内部向jinja发送变量

@blueprint.route('/')
@include_sidebar_data
def frontpage():

    return render_template('template.html')

您可以创建一个装饰函数,如下所示:

def include_sidebar_data(fn):
    template_name = fn()
    var1, var2, var3 = generate_sidebar_data()
    def wrapped():
        return render_template(template_name, var1=var2, var2=var2)
    return wrapped

@blueprint.route('/')
@include_sidebar_data
def frontpage():

    return 'template.html'

您可以使用上下文处理器():

UPD:我更喜欢下一个示例,如果将装饰器用于多个视图功能,效果会更好:

sidebar_data_views = []


def include_sidebar_data(fn):
    sidebar_data_views.append(fn.__name__)
    return fn


@blueprint.context_processor
def additional_context():
    # this code work if endpoint equals to view function name
    if request.endpoint not in sidebar_data_views:
        return {} 
    var1, var2, var3 = generate_sidebar_data()
    return {
        'var1': var1,
        'var2': var2,
        'var3': var3,
    }


@blueprint.route('/')
@include_sidebar_data
def frontpage():
    return render_template('template.html')

我将提出一些比使用装饰器或模板方法或类似方法更简单的方法:

def render_sidebar_template(tmpl_name, **kwargs):
    (var1, var2, var3) = generate_sidebar_data()
    return render_template(tmpl_name, var1=var1, var2=var2, var3=var3, **kwargs)

是的,只是一个函数。这就是你真正需要的,不是吗?有关灵感,请参见烧瓶片段。它本质上是在不同的上下文中做完全相同的事情。

我确实使用了上下文处理器,但挂断了“@blueprint”部分。我的decorator不在蓝图中,因此没有可用的“@app”或“@blueprint”来使用@app decorator,它为所有具有任何蓝图的应用程序添加上下文。@tbicr旧注释,我知道。但是你在示例中拼错了“blueprint”。非常干净-我喜欢它。@dmonoply说了什么。即使在2016年,这仍然很有帮助。谢谢,+1。@gf_u即使在2018年,我也不认为这更简单,如果我有几个视图需要相同的数据呢?无需重写这些变量即可在每个变量上呈现_模板
def render_sidebar_template(tmpl_name, **kwargs):
    (var1, var2, var3) = generate_sidebar_data()
    return render_template(tmpl_name, var1=var1, var2=var2, var3=var3, **kwargs)