Подтвердить что ты не робот

Как я могу отправлять переменные в шаблон Jinja из декоратора Flask?

Множество маршрутов вокруг моего приложения, предназначенного для рисования, должно будет отправить "данные боковой панели" в jinja.

Я ищу наиболее эффективный способ сделать это. Они должны быть чем-то лучше, чем импортировать мою функцию generate_sidebar_data() в каждый проект, многократно повторяя:

var1, var2, var3 = generate_sidebar_data()

а затем отправив их с помощью 'render_template':

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

Я хочу, чтобы это декоратор, который я могу положить с помощью маршрута, который будет делать то же самое, что и выше (выполняет функцию и отправляет vars в jinja), но я не знаю, возможно ли это. Как вы отправляете переменные в jinja изнутри функции декоратора?

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

    return render_template('template.html')
4b9b3361

Ответ 1

Я собираюсь предложить что-то еще более простое, чем использовать метод декоратора или шаблона или что-то в этом роде:

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)

Yup, просто функция. Это все, что вам действительно нужно, не так ли? См. this Флажок для вдохновения. Это по сути делает то же самое, в другом контексте.

Ответ 2

Вы можете использовать процессор контекста (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')

Ответ 3

Вы можете создать функцию декоратора следующим образом:

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'