it-swarm.com.de

umleiten, während Argumente übergeben werden

Im Kolben kann ich das machen:

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

Wenn foo.html {{ messages['main'] }} enthält, zeigt die Seite hello an. Was aber, wenn es eine Route gibt, die zum Foo führt:

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

In diesem Fall ist die einzige Möglichkeit, zu foo.html zu gelangen, wenn diese Logik ohnehin geschehen soll, über eine 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'

Wie kann ich also die Variable messages an die foo-Route übergeben, damit ich nicht den gleichen Logikcode neu schreiben muss, den diese Route berechnet, bevor sie geladen wird?

36
limp_chimp

Sie können die Nachrichten als explizite URL-Parameter (entsprechend codiert) übergeben oder die Nachrichten in der Variablen session (cookie) speichern, bevor Sie sie umleiten, und die Variable abrufen, bevor Sie die Vorlage rendern. Zum Beispiel:

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))

(Das Kodieren der Sitzungsvariablen ist möglicherweise nicht erforderlich. Die Flasche behandelt sie möglicherweise, kann sich aber nicht an die Details erinnern.)

Oder Sie könnten wahrscheinlich nur Flask Message Flashing verwenden, wenn Sie einfache Nachrichten anzeigen möchten.

52

Ich bin ein wenig verwirrt. "foo.html" ist nur der Name Ihrer Vorlage. Es gibt keine inhärente Beziehung zwischen dem Routennamen "foo" und dem Vorlagennamen "foo.html".

Um das Ziel zu erreichen, den Logikcode nicht für zwei verschiedene Routen neu zu schreiben, würde ich einfach eine Funktion definieren und diese Funktion für beide Routen aufrufen. Ich würde die Weiterleitung nicht verwenden, da dies den Client/Browser tatsächlich umleitet, so dass zwei Seiten geladen werden müssen, um Ihnen Codierungszeit zu sparen

Vielleicht:

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"})

Ich habe das Gefühl, dass mir etwas fehlt, und es gibt einen besseren Weg, um das zu erreichen, was Sie versuchen (ich bin nicht wirklich sicher, was Sie versuchen).

2
Ben

Ich möchte erwähnen, dass url_for erst verwendet werden kann, wenn es den Flaschenimporten hinzugefügt wird! 

Ich verbrachte eine Stunde damit, herauszufinden, warum es nicht funktionieren würde, da dies auf mehreren Websites nicht erwähnt wurde !!!

Fügen Sie url_for zur Liste der Importe wie folgt hinzu:

from flask import Flask, render_template, request, redirect, session, url_for
1
saltydog

Ich habe festgestellt, dass keine der Antworten hier auf meinen speziellen Anwendungsfall zutrifft. Ich dachte, ich würde meine Lösung teilen. 

Ich habe versucht, einen nicht authentifizierten Benutzer mit allen möglichen URL-Parametern zur öffentlichen Version einer App-Seite umzuleiten. Beispiel:

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

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

Hier ist die Lösung, die für mich funktioniert hat. 

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

Hoffe das hilft jemandem!

0
Nick Woodhams