Variable in Flask für weitere URL merken.

Django, Flask, Bottle, WSGI, CGI…
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Hallo zusammen,
ich würde gerne eine Variable (oder mehrere) welche unter der URL /seite1 erstellt wurde, an die darauf folgende URL /seite2 "weitergeben".
Seite1 enthält ein kleines Formular, welches der Client ausfüllen kann. Wenn dieser nun sein Formular sendet, soll eine weitere Seite mit Fragen öffnen, aber auch die Information von Seite1 angezeigt werden.
Die Seiten sehen nicht identisch aus, haben also jeweils ein anderes Layout (render_template).
Das genaue URL Prozedere habe ich leider noch nicht verstanden.

Code: Alles auswählen

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


@app.route("/seite2", methods=["GET", "POST"])
def seite2(text1):
    return render_template("seite2.html")
seite1.html

Code: Alles auswählen

{% extends "layouts/main.html" %}

{% block content %}
    <br>
    <br>
    <h4>Seite 1</h4>
    <form method=post enctype=multipart/form-data>
        <input type="text" name="text1">
        <input type="submit" value="Daten speichern"><br>
    </form>
{% endblock %}
seite2.html

Code: Alles auswählen

{% extends "layouts/main.html" %}

{% block content %}
    <br>
    <br>
    <h4>{{ text1 }}</h4>
{% endblock %}
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tz_wuerzburg: Was funktioniert denn an dem gezeigten nicht?
„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,

basierend auf dem, wie es beschreibst, brauchst du auch keine Route für `seite2`, weil ein direkter Aufruf des Templates `seite,html` keinen Sinn macht, wenn man vorher nicht aus `seite1` war.

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

@blackjack
Das ganze funktioniert einwandfrei. Ich versuche nur zu verstehen, ob ich auf dem richtigen Weg bin. Bzw. die Lösung eine Gute ist.

@noisefloor
Genau, Seite2 ist nur über Seite1 erreichbar. Wenn auf Seite1 "Daten speichern" bestätigt wird, werden die Daten aus der Variablen "text1" mit zu Seite2 genommen. Ansonsten muss Seite2 nicht erreichbar sein.

Grundsätzlich. Wenn von zwei (oder mehreren) Clients auf Seite1 zugegriffen wird und die Variable "text1" gefüllt wird, wie verhält sich Flask dann? Wird die Variable immer wieder vom
aktuellsten Ereignis überschrieben? Falls ja, wie bekommt man sowas in den Griff? Also wie ist es Möglich, eine Variable für viele Clients zur Verfügung zu stellen? Mit Sessions?

Vielen Dank!
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Du stellst ja gar keine Variable zur Verfügung, sondern der Browser kennt die Werte und schickt sie, bei Dir, per POST-Request mit.

Kannst Du genauer beschreiben, was Du machen willst? Ich versteh nur Seite1 und Seite2.
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Ich stelle doch seite2 über die Variable "text1" Informationen zur Verfügung. Und auf seite1 wird diese durch den Client über den Browser mit Informationen gefüllt.

Was es werden soll:

- Der Client meldet sich auf der Seite mit seinem Username und seinem Passwort an
- Der angemeldete Client geht auf seite1 und lädt dort Daten hoch. z.B. ein.txt File
- Der Client wird durch das bestätigen des Buttons "Daten hochladen" auf seite2 geleitet
- Auf seite2 werden dem Client Informationen zur eben hochgeladenen Datei angezeigt, er hat auf seite2 die Optionen weitere Angaben zur eben hochgeladenen Datei zu machen.
- Danach folgt dann seite3. Hier werden dann Informationen der ersten beiden seiten angezeigt. Es gibt auch hier weitere optionale Auswahlmöglichkeiten.
- Sind alle Informationen zu der hochgeladenen Datei zusammengesammelt kann der Client diese bestätigen und sich wieder am System abmelden.
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tz_wuerzburg: Das kann man so machen wie Du das im Beispiel machst, in dem man immer alle Informationen von einer Seite wieder in der nächsten mit ausliefert und danach wieder zum Server überträgt um sie in der nächsten Seite wieder auszuliefern. Dann muss der Benutzer das aber tatsächlich in einem Durchgang machen. Wenn er im letzten Schritt dann aus versehen Tab oder Fenster schliesst, das Gerät wegen Akku ausgeht, oder ähnliches, dann sind alle eingegebenen Informationen verloren. (Aber die Datei noch auf dem Server, denn *die* wird man ja nicht immer hin und her schicken wollen.)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du kannst Daten durch verschiedene Formulare mittels hidden input fields durchschleifen, aber das ist ganz schoen anstrengend. Stattdessen waere es einfacher, eine Session einzufuehren, die fuer einen eingeloggten User gilt, und da die Daten zu hinterlegen. Was dadurch allerdings kaputt gehen kann ist das mehrfache verwenden der Seite in mehreren Tabs. Um dem wiederum vorzubeugen kann man nur einen Key benutzen, der zB zufaellig auf Seite 1 generiert wird, und der die Daten fuer einen Workflow zusammenfasst.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Wenn von zwei (oder mehreren) Clients auf Seite1 zugegriffen wird und die Variable "text1" gefüllt wird, wie verhält sich Flask dann? Wird die Variable immer wieder vom
aktuellsten Ereignis überschrieben?
Für jede Verbindung wird die an die Route gebundene Funktionen separat ausgeführt. Du hast von außen keine Zugriff auf parallele Zugriffe auf die gleiche Seite (muss ja auch so sein, weil das sonst eine Sicherheitslücke wäre).

Gruß, noisefloor
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Man könnte auch einfach die Schritte alle nur im Browser über JS implementieren und alles in einem Request an die Webanwendung schicken.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum verteilst Du die Eingaben auf drei Seiten?
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Vielen Dank für Eure Antworten!

@Sirius3
Finde ich einfach optisch schöner, die Seite ist nicht so überladen. Außerdem kann der Client auf seite1 eine Datei wählen, der Server wertet diese aus
und gibt dem Client auf seite2 erste Information mit. Auf diese Informationen kann der Client dann mit einer weiteren Auswahl reagieren. Wichtig ist auch, bei Python,
HTML uns CSS bleiben zu können. Ersteinmal.

@DasIch
Ein sehr guter Einwand. Ich bin in Sachen Python und generell der Programmierung aber noch am Anfang und möchte deshalb ausschließlich bei Python bleiben.
Vermutlich würde ich mich verzetteln.

@noisefloor
Um die Verbindung kümmert sich Flask, oder muss ich die über eine Session sicherstellen?
Wenn Client1 Daten an seite1 übergibt werden diese ja dann über die Variable text1 an seite2 übergeben. Woher weiß seite2 von welchem Client gerade der Inhalt
text1 kommt?

@__deets__
Mit mehreren Tabs meinst du mehrere Tabs bei Client1 im Browser oder an sich verschieden Tabs verteilt auf unterschiedlichen Clients? Ich arbeite mit einem Zeitstempel, ist sowas
als Schlüssel zu empfehlen?

@__blackjack__
Das "durchklicken" der Seiten ist aktuell leider alternativlos, da ich noch zu wenig Ahnung von Datenbanken habe. Aktuell werden die wichtigsten Daten der jeweiligen Seite in einem
.txt File gespeichert und ausgelesen falls etwas benötigt wird.
Daher wird auch das Risiko eines Abbruchs durch den Client in Kauf genommen. Um doppelte Dateinamen zu vermeiden, setzte ich auf einen umfangreichen Zeitstempel. In Kombination
mit dem Dateinamen sollte nichts schief gehen. Der Client darf also ein zweites mal starten.
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tz_wuerzburg: Die Seiten wissen gar nichts. Ich verstehe auch nicht so recht was Du mit wissen von welchem Client der Inhalt kommt meinst. Die Daten kommen von einem Client und die Antwort wird wieder an diesen Client zurück geschickt. Welcher das genau ist, braucht man doch gar nicht wissen, es gibt ja nur den einen den der Code gerade behandelt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Eine session arbeitet mit einem Cookie, der ist ueblicherweise nur in einem Browser vorhanden. Es waeren also mehrere Tabs in einem Browser. Und ein Zeitstempel ist nicht zu empfehlen, denn da kann es ja leicht zu einem Konflikt kommen. Eine GUID ist leicht erzeugt.
tz_wuerzburg
User
Beiträge: 71
Registriert: Dienstag 7. März 2017, 17:51

Hallo zusammen,
was passiert denn, wenn zwei Variablen zurück gegeben werden sollen? Erreiche ich text1 und text2 mit meinem return überhaupt?
Wie sage ich Python, dass text1 und text2 verarbeitet werden sollen, falls gefüllt. Wenn text1 gefüllt ist, wird text2 ja nicht mehr beachtet.

Code: Alles auswählen

@app.route("/seite1", methods=["GET", "POST"])
def seite1():
    if request.method == "POST":
        if request.form["text1"] != "":
            text1 = request.form["text1"]
            print(text1)
        elif request.form["text2"] != "":
            text2 = request.form["text2"]
            print(text2)
        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)
Benutzeravatar
__blackjack__
User
Beiträge: 13116
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: 17754
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: 17754
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)
Antworten