Variable in Flask für weitere URL merken.

Django, Flask, Bottle, WSGI, CGI…
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tz_wuerzburg: Diese Frage hat irgendwie nichts mit Flask zu tun. Das ist ganz normaler Programmablauf und ist fehlerhaft. Zum einen das ``elif``, weil wie Du ja schon geschrieben hast dieser Zweig nicht erreicht wird wenn "text1" ungleich der leeren Zeichenkette ist, zum anderen ist ja aber auch die Definition von `text1` nicht garantiert wenn da die ``if``-Bedingung nicht zutrifft. Wenn nicht beide `text1` und `text2` definiert sind, dann wird die vorletzte Zeile von `seite1()` zu einem `NameError` führen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

@tz_wuerzburg: was soll im Fall, dass text1 nicht gefüllt ist, denn passieren? Bei FORMS sollte man nie voraussetzen, dass die Felder auch gefüllt sind, oder irgendeinen vorgegebenen Inhalt haben, weil jeder /seite1 auch mit beliebigen Inhalten aufrufen kann.

Code: Alles auswählen

def seite1():
    if request.method == "POST":
        text1 = request.form.get("text1")
        text2 = request.form.get("text2")
        if not text1:
            was_soll_hier_passieren()
        if not text2:
            was_soll_dann_passieren()
        return render_template("seite2.html", text1=text1, text2=text2)
    return render_template("seite1.html")
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

@ __blackjack__
Sorry, Du hast Recht. Mit diesem Post möchte ich auch den Ausflug in das neue Thema beenden.

Hier nun noch meine Idee. Es macht auf jeden Fall gerade das, was es soll.

Code: Alles auswählen

@app.route("/seite1", methods=["GET", "POST"])
def seite1():
    if request.method == "POST":
        text1 = request.form["text1"]
        text2 = request.form["text2"]
        text_table = [text1, text2]
        for row in text_table:
            if row != "":
                return render_template("seite2.html", text1=text1, text2=text2)

    return render_template("seite1.html")


@app.route("/seite2", methods=["GET", "POST"])
def seite2(text1, text2):
    return render_template("seite2.html", text1=text1, text2=text2)
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

@tz_wuerzburg: Du hast immer noch nicht erklärt, was passieren soll, wenn ein Text leer ist. Wenn ich ratel, was Dein Code eigentlich machen soll, würde ich sagen, dass sobald text1 oder text2 nicht leer ist, Seite2 angezeigt werden soll, sonst Seite1.

Code: Alles auswählen

def seite1():
    if request.method == "POST":
        text1 = request.form.get("text1", "")
        text2 = request.form.get("text2", "")
        if text1 or text2:
            return render_template("seite2.html", text1=text1, text2=text2)
    return render_template("seite1.html")
Ob man das als Nutzer will, immer wieder kommentarlos die erste Seite angezeigt bekommen, wenn man falsche Angaben macht, steht auf einem anderen Blatt.
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

@ Sirius3
Ich möchte, dass bei text1 immer weitergeleitet wird. Bei text2 nur dann, wenn text1 auch vorhanden ist.
Darauf würde ich den Client auf der Seite hinweisen.

Code: Alles auswählen

@app.route("/seite1", methods=["GET", "POST"])
def seite1():
    if request.method == "POST":
        text1 = request.form["text1"]
        text2 = request.form["text2"]
        if request.form["text1"] != "" and request.form["text2"] != "":
            return render_template("seite2.html", text1=text1, text2=text2)
        elif request.form["text1"] != "":
            return render_template("seite2.html", text1=text1)

    return render_template("seite1.html")


@app.route("/seite2", methods=["GET", "POST"])
def seite2(text1, text2):
    return render_template("seite2.html", text1=text1, text2=text2)
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

Ergo, reicht die Abfrage auf text1:

Code: Alles auswählen

def seite1():
    if request.method == "POST":
        text1 = request.form.get("text1", "")
        text2 = request.form.get("text2", "")
        if text1:
            return render_template("seite2.html", text1=text1, text2=text2)
    return render_template("seite1.html")
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tz_wuerzburg: Da wird doch aber in beiden Fällen mit der zweiten Seite geantwortet. Und wenn Du in der ersten Seite auf fehlende Daten hinweisen möchtest, dann muss die doch auch Werte für's Template entgegennehmen.

Übrigens wird in keinem Fall weitergeleitet! Du antwortest ja mit dem Template "seite2.html" unter der URL "/seite1".

Und bei der URL "/seite2" sehe ich gerade nicht wo die Argumente `text1` und `text2` herkommen sollten‽
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@tz_wuerzburg: ich glaube, du hast noch nicht wirklich verstanden, was da wirklich abläuft. Wie __blackjack__ schon sagte: es ist ein normaler Programmablauf. Was lediglich dazu kommt ist, dass an eine Route eine Funktion gebunden ist. Die Funktion ist eine _normale_ Python-Funktion. Heißt auch, dass lokale Variablen nur im Scope der Funktion gültig sind. Wenn du irgendwo Daten von außerhalb brauchst musst du die Funktion halt irgendwie bereit stellen (Datenbank, Queue, Textdatei und was es sonst noch so gibt).

Und noch ein Tipp: für alles außer mega-triviale Formulare ein Formularframework benutzen. Dann kann man die Validierung der Daten dahin auslagern. Unter Python ist, wenn man nicht gerade Django verwendet, Wtforms sehr gängig. Dafür gibt es auch Bindings für Flask.

Gruß, noisefloor
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Hallo zusammen,
vielen Dank für die vielen Hinweise.
Ich habe nun verstanden.

Der Code schiebt die variablen Angaben weiter in das Template von Seite2. Die Route dorthin wird nicht benutzt.

Code: Alles auswählen

@app.route("/seite1", methods=["GET", "POST"])
def seite1():
    if request.method == "POST":
        text1 = request.form["text1"]
        text2 = request.form["text2"]
        if request.form["text1"] and request.form["text2"] != "":
            return render_template("seite2.html", text1=text1, text2=text2)
        elif request.form["text1"] != "":
            return render_template("seite2.html", text1=text1)
        else:
            context = "Bitte geben Sie mindestens text1 an!"
            return render_template("seite1.html", context=context)

    return render_template("seite1.html")
Dieser Code ist für den oberen Teil nicht von Bedeutung, bzw. wird nicht verwendet:

Code: Alles auswählen

@app.route("/seite2", methods=["GET", "POST"])
def seite2(text1, text2):
    return render_template("seite2.html", text1=text1, text2=text2)
Das bringt mich aber nun zu meinem eigentlichen Problem. Ich möchte ja von Seite1 mit Daten auf Seite2 "wandern". Ich habe schon verstanden, ich müsste die
Daten aus den Variablen zwischenspeichern, z.B. in einer .txt Datei.
Was ist aber, wenn die Informationen aus "text1" benötigt werden, um eine .txt zu finden, bzw. zu öffnen?

Das habe ich leider noch nicht ganz verstanden.

Code: Alles auswählen

@app.route("/seite2", methods=["GET", "POST"])
def seite2(text1):
    with open(text1, "r", newline="", encoding="utf-8") as input_file:
        read_file = csv.reader(input_file, delimiter="\t")
        for row in read_file:
           seite1_list = row 
        return render_template("seite2.html", seite1_list=seite1_list)
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tz_wuerzburg: Was heisst denn »auf Seite 2 ”wandern”«? Du kannst da ja mehrere Seiteninhalte nacheinander unter *einer* URL verfügbar machen.

Wenn sich die URL ändern soll, dann halt nicht über den Server sondern über den Browser. Das heisst unter der ersten URL lieferst Du ein Formular aus das dann an die zweite URL gesendet wird und nicht an die erste.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Ich möchte ja von Seite1 mit Daten auf Seite2 "wandern". Ich habe schon verstanden, ich müsste die
Tust du doch jetzt schon in der Route "seite1"?!

Eine Route muss nicht gleichbedeutend mit genau einem Template sein. Kann, muss aber nicht.

Was bringt dich denn zu der Überzeugung, dass du aktuell zwingend eine 2. Route brauchst? Dein Programmentwurf und die Fallstricke sind ja weiter oben schon mal diskutiert worden.

Gruß, noisefloor
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Hallo zusammen,

ich weiß leider nicht, oder kann nicht verstehen, wie es nach dem "return render_template" für mich weitergehen soll.
Es wird eine schöne neue Seite2 aus den Eingaben von Seite1 gerendert.
Aber wo kommt jetzt der Code mit seinen Funktionen und Abfragen für Seite2 hin? Das return gibt doch die generierte Seite2
zurück...
Mir fehlt das Wissen, Seite3 näher zu kommen.

Vielen Dank und einen schönen Abend noch!
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

Nach dem `return` geht es gar nicht weiter, denn dann ist die Anfrage vom Browser beantwortet.

Eine URL könnte https://example.com/seite1.html oder https://example.com/seite2.html sein und führt zu verschiedenen Routen. Die URLs können aber auch https://example.com/upload?page=1 und https://example.com/upload?page=2 heißen, was die selbe Route `upload` wäre, aber mit unterschiedlichen Parametern. Dass Deine Route `seite1` heißt, aber nach dem zweiten Schema arbeitet, ist etwas verwirrend. Statt `page` kannst Du natürlich irgendetwas anders nehmen, anhand dessen Du erkennen kannst, welche Seite gerade angefragt wird.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Es wird eine schöne neue Seite2 aus den Eingaben von Seite1 gerendert.
Aber wo kommt jetzt der Code mit seinen Funktionen und Abfragen für Seite2 hin?
Aktuell: nirgendwo. Wie du ja selber sagst liefert die Route `seite1` das Template `seite2` aus und - zumindest nach den Codebeispielen von dir - kann die Funktion `seite1` auch alle Variablen für das Template `seite2` liefern.

Die möglichen Techniken, Daten über mehrere Requests zu erhalten, sind dir alle genannt worden: über URL-Parameter, Cookies, Session Framework, Hidden Field im Formular, temporäre persistente Datenspeicherung. Letzteres ist IMHO der umständlichste Weg, weil du eine Art Session Framework selber nachbaust.

Vielleicht solltest du mal ein bisschen konkreter werden, was du genau vor hast und welche Daten wann warum nochmals gebraucht werden. Aktuell ist das ja alles sehr vage.

Gruß, noisefloor
Antworten