2013-06-12 11 views
28

W kolbie, mogę to zrobić:przekierować przechodząc argumenty

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

A jeśli foo.html zawiera {{ messages['main'] }}, strona pokaże hello. Ale co, jeśli nie jest to droga, która prowadzi do foo:

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

W tym przypadku jedynym sposobem, aby dostać się do foo.html, jeśli chcę, że logika się zdarzyć i tak, jest przez 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' 

Jak zatem uzyskać tę zmienną messages, która ma zostać przekazana do trasy foo, aby nie musiałem po prostu przepisywać tego samego kodu logicznego, który jest obliczana przez tę trasę przed jej załadowaniem?

Odpowiedz

41

Możesz przekazać wiadomości jako jawny parametr adresu URL (odpowiednio zakodowany) lub zapisać wiadomości w zmiennej session (cookie) przed przekierowaniem, a następnie pobrać zmienną przed renderowaniem szablonu. Na przykład:

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

(kodującego zmienną sesji może nie być konieczne, kolba może być posługiwaniu się nim dla ciebie, ale nie mogę sobie przypomnieć szczegóły)

Albo można prawdopodobnie wystarczy użyć Flask Message Flashing jeśli tylko muszą pokazywać proste wiadomości.

+3

+1, miganie wiadomości jest zdecydowanie droga do przebycia. –

+0

numpy array daje typError z sesją, mówi, że nie jest serializowany JSON – erogol

+0

Problem z sesją w tym przypadku można mieć warunek wyścigu: jeśli ktoś poprosi o tę samą stronę dwa razy w tym samym czasie, może dostać wiadomości na niewłaściwej. – bfontaine

2

Jestem trochę zdezorientowany. "foo.html" to po prostu nazwa twojego szablonu. Nie ma nieodłącznego związku między nazwą trasy "foo" a nazwą szablonu "foo.html".

Aby osiągnąć cel polegający na nie przepisywaniu kodu logicznego dla dwóch różnych tras, po prostu zdefiniowałbym funkcję i zadzwoniłbym do niej w przypadku obu tras. Nie użyłbym przekierować dlatego, że faktycznie przekierowuje klienta/przeglądarki, która wymaga, aby załadować dwie strony zamiast jednego, żeby zaoszczędzić trochę czasu kodowania - co wydaje się oznaczać :-P

Więc może:

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

Czuję, że coś przeoczyłem i istnieje lepszy sposób na osiągnięcie tego, co próbujesz zrobić (nie jestem pewien, co próbujesz zrobić)