flask form problem

Django, Flask, Bottle, WSGI, CGI…
Antworten
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

moin,

ich hab hier gerade ein warscheinlich sehr simples problem, dennoch finde ich keine lösung.

Code: Alles auswählen

from flask import Flask, request

app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def submit_token():
    if request.method == 'POST':
#        token = request.form['token']
        token = request.form.token
        print token

    return '''
    <!doctype html>
    <title>Test Form</title>
    <h1>TEST POST FORM</h1>
    <form action="" method=post enctype=text/plain>
        <p><input type=text name=token >
            <input type=submit value=Submit>
    </form>
    '''
app.run(debug=True)
Ich möchte eigentlich nur den userinput des forms der variable token zuweisen, aber leider sind mir die ideen ausgegangen, hab ich nichts weiteres dazu in der doku gefunden, jedenfalls nichts was mein problem lösen würde.
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

Kenn mich zwar mit der flask template engine nicht aus, aber probiere es mal mit "" im Formular
zB: name="name" type="text" ...
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo taake,
was hast Du da für einen seltsamen enctype?
Der sollte entweder »application/x-www-form-urlencoded«, was der default ist, oder wenn Du Dateien verschicken willst »multipart/form-data«.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Hey,

den enctype hab ich im netz gefunden - weil sollte ein text feld sein.
Ist ein paar Jahre her das ich mich mit HTML beschäftigt habe.

Hab im großen und ganzen das ganze aus nem howto entnommen dort gabs ein file upload form

Code: Alles auswählen

<!doctype html>
    <title>Upload new File</title>
    <h1>Upload new File</h1>
    <form action="" method=post enctype=multipart/form-data>
        <p><input type=file name=file>
            <input type=submit value=Upload>
    </form>
Und da wird das file das hochgeladen wird so behandelt:

Code: Alles auswählen

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        [...]
das heißt ich kann für alles was kein file ist application/x-www-form-urlencoded nehmen?

Habs zumindest gerade ausprobiert aber das Problem besteht weiterhin flask server crashed wenn ich was eingebe:

AttributeError: 'ImmutableMultiDict' object has no attribute 'token'
Wie gesagt leider keine Ideen mehr wie ich das was ins form eingetragen wird abgreifen kann.
Zuletzt geändert von taake am Donnerstag 18. April 2013, 12:30, insgesamt 1-mal geändert.
BlackJack

@taake: Also erst einmal würde ich wieder die auskommentierte Zeile für den Zugriff auf 'token' verwenden. Und dann weiss ich gerade nicht aus dem Kopf ob das 'name'- oder das 'id'-Attribut in HTML angibt was der Bezeichner des Wertes bei der Übertragung ist. Ich setze in der Regel beides auf den gleichen Wert.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Danke BlackJack, das hat weiter geholfen.

Scheinbar muss der type auch token sein, wenn type und name übereinstimmen klappt es

Code: Alles auswählen

from flask import Flask, request

app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def download_file():
    if request.method == 'POST':
        token = request.form['token']
        print token

    return '''
    <!doctype html>
    <title>Download File</title>
    <h1>Download File</h1>
    <form action="" method=post enctype=application/x-www-form-urlencoded>
        <p><input type=token name=token >
            <input type=submit value=Download>
    </form>
    '''

app.run(debug=True)
So läufts, danke euch :)
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo taake,

mit Deiner Methode, solange zu raten, bis es funktioniert, wirst Du, sobald es komplexer wird, nicht mehr weiter kommen. Lies Dir eine HTML-Einführung Deiner Wahl durch. »type=token« gibt es nicht und wird von gutmütigen Browsern in »type=text« interpretiert. Dass »request.form« ein Dictionary ist, und keinen Attributzugriff hat, steht so in der flask-Dokumentation und auch in allen Beispielen.

@BlackJack: Formularvariablennamen werden nur nach dem »name«-Attribut benannt, »input«-Felder ohne Namen werden erst gar nicht übertragen.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

taake hat geschrieben:

Code: Alles auswählen

    <form action="" method=post enctype=application/x-www-form-urlencoded>
        <p><input type=token name=token >
            <input type=submit value=Download>
    </form>
So läufts, danke euch :)
So läuft es eher zufällig aufgrund der Fehlertoleranz des verwendeten Browsers. Korrekt ist es aber nicht.

Richtig wäre es so.

Code: Alles auswählen

    <form action="" method="post" enctype="application/x-www-form-urlencoded">
        <p><input type="token" name="token">
            <input type="submit" value="Download">
    </form>
Mal abgesehen davon ist type="token" ungültig.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

/me hat geschrieben:Mal abgesehen davon ist type="token" ungültig.
action="" ist auch ungültig.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@/me: Du verwechselst XHTML und HTML: In HTML sind Attribute ohne Anführungszeichen korrekt solange sie die folgenden Zeichen nicht enthalten: ",<,>,' und Leerzeichen jeglicher Art.
nomnom hat geschrieben:action="" ist auch ungültig.
ganz im Gegenteil:
RFC 2396 hat geschrieben:However, if the URI reference occurs in a context that is always intended to result in a new request, as in the case of HTML's FORM element, then an empty URI reference represents the base URI of the current document and should be replaced by that URI when transformed into a request.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Nachtrag:
... o.O

Wenn ich alles wie mehrfach angemerkt in "" setze läuft es auch mit type="text" ... verstehen tu ich das ganze nicht wirklich.
Aber okay, solange es konform ist und geht, ist es gut.

@nomnom:
Was kann schlimmstenfalls passieren wenn action="" leer ist?
Bzw. es läuft auch wenn ich action="" weglasse.
Benötige ich glaube ich gar nicht, weil das form als solches soll ja gar nichts machen, den input krallt sich doch flask, oder bin ich jetzt auf dem holzweg?

Edit:

@ Sirius3:

Danke für die Aufklärung, bleibt action="" also drin.
Sirius3 hat geschrieben:@/me: Du verwechselst XHTML und HTML: In HTML sind Attribute ohne Anführungszeichen korrekt solange sie die folgenden Zeichen nicht enthalten: ",<,>,' und Leerzeichen jeglicher Art.
Bleibt aber die Frage offen warum

Code: Alles auswählen

[...]
token = request.form['token']
[...]
<form action="" method="post" enctype="application/x-www-form-urlencoded">
        <p><input type="text" name="token" >
            <input type="submit" value="Download">
</form>
läuft und

Code: Alles auswählen

[...]
token = request.form['token']
[...]
<form action="" method=post enctype=application/x-www-form-urlencoded>
        <p><input type=text name=token >
            <input type=submit value=Download>
</form>
nicht läuft.
Zuletzt geändert von taake am Donnerstag 18. April 2013, 13:54, insgesamt 1-mal geändert.
BlackJack

@taake: Holzweg. Wie soll sich flask etwas „krallen”? Das Form wird im Browser dargestellt. Da hat flask keinen Zugriff drauf denn flask läuft auf dem Server. Der Browser muss also wissen was er mit den Form-Daten machen soll wenn jemand den Submit-Button klickt. Und das sagt man dem Browser unter anderem mit dem action-Attribut vom Form.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

taake hat geschrieben:oder bin ich jetzt auf dem holzweg?
füg zu Deiner Liste, was Du unbedingt noch anschauen solltest HTTP hinzu.

Es gibt ein Protokoll über das sich Dein Browser mit dem Server in flask unterhalten. Forms sind eine Art, wie der Nutzer Daten eingeben und dem Browser anweisen kann, diese an den Server zu schicken. Der Server verpack diese Daten schön in request.form, wo Du sie dann wieder auspacken kannst. Du mußt jetzt den Weg nicht im einzelnen kennen, aber dass es bestimmte Stationen auf diesem Weg gibt, schon.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Sirius3 hat geschrieben:
taake hat geschrieben:oder bin ich jetzt auf dem holzweg?
füg zu Deiner Liste, was Du unbedingt noch anschauen solltest HTTP hinzu.

Es gibt ein Protokoll über das sich Dein Browser mit dem Server in flask unterhalten. Forms sind eine Art, wie der Nutzer Daten eingeben und dem Browser anweisen kann, diese an den Server zu schicken. Der Server verpack diese Daten schön in request.form, wo Du sie dann wieder auspacken kannst. Du mußt jetzt den Weg nicht im einzelnen kennen, aber dass es bestimmte Stationen auf diesem Weg gibt, schon.
Also eigentlich nein, denke nicht.
Denke nicht das es dafür notwenig ist haargenau zu wissen was http wie genau macht,
also wenn ich mich nicht total irre dann kümmert sich die methode post darum das die daten zum server zurück kommen.
Meine frage bezog sich eher darauf ob man das action weglassen kann, da man ja durch das abschicken des forms keine weitere scripte what ever auf dem server triggern will.
Will mir ja nur den userinput aus dem form abgreifen, der durch das post zurück kommt.
Also Quasi ohne action, einfach ein "zurück an absender"

Aber die Frage ob das action nötig ist hast du ja bereits beantwortet, danke dafür.
Zuletzt geändert von taake am Donnerstag 18. April 2013, 14:30, insgesamt 2-mal geändert.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Sirius3 hat geschrieben:@/me: Du verwechselst XHTML und HTML: In HTML sind Attribute ohne Anführungszeichen korrekt solange sie die folgenden Zeichen nicht enthalten: ",<,>,' und Leerzeichen jeglicher Art.
Man lernt doch immer hinzu. Ich habe halt jahrelang nur XHTML geschrieben, das frisst sich ins Gehirn ein.
BlackJack

@taake: Es wird jetzt nicht so ganz klar aus dem was Du schreibst: Es werden nicht nur die Daten an den Server übertragen, sondern der Browser erwartet da auch eine Antwort, zum Beispiel in Form einer Webseite. Und dafür wird die Funktion getriggert die in Deiner Webanwendung unter der Route hinterlegt ist, die bei `action` hinterlegt ist, oder eben der Route für das gerade angezeigte Dokument wenn da "" angegeben wird.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Sirius3 hat geschrieben:
nomnom hat geschrieben:action="" ist auch ungültig.
ganz im Gegenteil:
RFC 2396 hat geschrieben:However, if the URI reference occurs in a context that is always intended to result in a new request, as in the case of HTML's FORM element, then an empty URI reference represents the base URI of the current document and should be replaced by that URI when transformed into a request.
http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#attr-fs-action hat geschrieben:The action and formaction content attributes, if specified, must have a value that is a valid non-empty URL potentially surrounded by spaces.
und eine Zeile darunter :cry:
The action of an element is the [...] empty string.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@nomnom: Ja, das ist schon schade, dass man sich auf Informationen im Internet nicht blind verlassen kann. Zumal URL auf jeden Fall falsch ist, weil URLs nur absolute Adressen inklusive http:// bezeichnen.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Sirius3 hat geschrieben:@nomnom: Ja, das ist schon schade, dass man sich auf Informationen im Internet nicht blind verlassen kann. Zumal URL auf jeden Fall falsch ist, weil URLs nur absolute Adressen inklusive http:// bezeichnen.
Ich hatte validator.w3.org benutzt. Aber naja, ;)
Antworten