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

перенаправление при передаче аргументов

В колбе я могу это сделать:

render_template("foo.html", messages={'main':'hello'})

И если foo.html содержит {{ messages['main'] }}, страница покажет hello. Но что, если есть маршрут, который приводит к foo:

@app.route("/foo")
def do_foo():
    # do some logic here
    return render_template("foo.html")

В этом случае единственный способ добраться до foo.html, если я хочу, чтобы эта логика произошла в любом случае, проходит через redirect:

@app.route("/baz")
def do_baz():
    if some_condition:
        return render_template("baz.html")
    else:
        return redirect("/foo", messages={"main":"Condition failed on page baz"}) 
        # above produces TypeError: redirect() got an unexpected keyword argument 'messages'

Итак, как мне получить эту переменную messages, которая будет передана на маршрут foo, так что мне не нужно просто переписывать тот же логический код, который этот маршрут вычисляет, прежде чем загружать его?

4b9b3361

Ответ 1

Вы можете передать сообщения как явный URL-адрес (соответствующим образом закодированным) или сохранить сообщения в переменной session (cookie) перед перенаправлением, а затем получить переменную перед отображением шаблона. Например:

def do_baz():
    messages = json.dumps({"main":"Condition failed on page baz"})
    session['messages'] = messages
    return redirect(url_for('.do_foo', messages=messages))

@app.route('/foo')
def do_foo():
    messages = request.args['messages']  # counterpart for url_for()
    messages = session['messages']       # counterpart for session
    return render_template("foo.html", messages=json.loads(messages))

(может потребоваться кодирование переменной сеанса, флешка может обрабатывать ее для вас, но не может вспомнить детали)

Или вы могли бы просто использовать Flask Message Flashing, если вам просто нужно показывать простые сообщения.

Ответ 2

Я немного смущен. "foo.html" - это просто имя вашего шаблона. Там нет неотъемлемой связи между именем маршрута "foo" и именем шаблона "foo.html".

Чтобы достичь цели не переписывать логический код для двух разных маршрутов, я бы просто определил функцию и вызвал ее для обоих маршрутов. Я бы не использовал перенаправление, потому что это фактически перенаправляет клиент/браузер, который требует, чтобы они загружали две страницы вместо одной, чтобы просто сохранить время кодирования - что кажется средним: -P

Итак, возможно:

def super_cool_logic():
    # execute common code here

@app.route("/foo")
def do_foo():
    # do some logic here
    super_cool_logic()
    return render_template("foo.html")

@app.route("/baz")
def do_baz():
    if some_condition:
        return render_template("baz.html")
    else:
        super_cool_logic()
        return render_template("foo.html", messages={"main":"Condition failed on page baz"})

Я чувствую, что у меня что-то не хватает, и есть лучший способ добиться того, что вы пытаетесь сделать (я не совсем уверен, что вы пытаетесь сделать)

Ответ 3

Я обнаружил, что ни один из ответов здесь не относится к моему конкретному варианту использования, поэтому я решил поделиться своим решением.

Я искал перенаправления неаутентифицированного пользователя на публичную версию страницы приложения с любыми возможными параметрами URL. Пример:

/app/4903294/my-great-car?email=coolguy%40gmail.com для

/public/4903294/my-great-car?email=coolguy%40gmail.com

Вот решение, которое сработало для меня.

return redirect(url_for('app.vehicle', vid=vid, year_make_model=year_make_model, **request.args))

Надеюсь, это поможет кому-то!