32

我的蓝图烧瓶应用程序周围的许多路线都需要向 jinja 发送“侧边栏数据”。

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

var1, var2, var3 = generate_sidebar_data()

然后用'render_template'发送它们:

return render_template('template.html',
                           var1=var1,
                           var2=var2,
                           var3=var3
                      )

我想要的是一个装饰器,我可以把它放在与上面做同样的事情的路线上(运行函数并将变量发送到 jinja),但我不知道这是否可能。如何从装饰器函数内部将变量发送到 jinja?

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

    return render_template('template.html')
4

3 回答 3

24

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

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)

是的,只是一个函数。这就是你真正需要的,不是吗?请参阅Flask Snippet 以获得灵感。它本质上是在不同的上下文中做同样的事情。

于 2013-04-07T13:37:14.303 回答
12

您可以使用上下文处理器(http://flask.pocoo.org/docs/api/#flask.Flask.context_processor):

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


@blueprint.route('/')
@include_sidebar_data
def frontpage():
    return render_template('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')
于 2013-04-07T07:54:57.347 回答
4

你可以像这样创建一个装饰器函数:

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'
于 2013-04-07T05:30:23.210 回答