Probleme beim Erstellen eines HTML-Formulars mittels Python Flask

Django, Flask, Bottle, WSGI, CGI…
Antworten
kopra
User
Beiträge: 2
Registriert: Mittwoch 30. Dezember 2020, 15:38

Hallo,

ich habe versucht, eine Website zu erstellen, auf der Daten zur Newsletteranmeldung eingegeben werden können.
Der Großteil funktioniert.
Allerdings erhalte ich folgende Fehlermeldung, wenn ich nicht alle Checkboxen auswähle:

Code: Alles auswählen

Bad Request

The browser (or proxy) sent a request that this server could not understand.
Mein Code sieht folgendermaßen aus:

index.html:

Code: Alles auswählen

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Anmeldung</title>
</head>
<body>
<h1>Anmeldung zum Newsletter</h1>
<form method="get" action="answer">
    <table>
        <tr>
            <td style="text-align:left"><label for="vorname">Vorname:</label></td>
            <td><input type="text" id="vorname" name="vorname" required="required"/></td>
        </tr>
        <tr>
            <td style="text-align:left"><label for="nachname">Nachname:</label></td>
            <td><input type="text" id="nachname" name="nachname" required="required"/></td>
        </tr>
        <tr>
            <td style="text-align:left"><label for="gebdatum">Geburtsdatum:</label></td>
            <td><input type="date" id="gebdatum" name="gebdatum" required="required"/></td>
        </tr>
        <tr>
            <td style="text-align:left"><label for="email">EMail-Adresse:</label></td>
            <td><input type="text" id="email" name="email" required="required"/></td>
        </tr>
        <tr>
            <td style="text-align:left"><label for="login">Login:</label></td>
            <td><input type="text" id="login" name="login" required="required"/></td>
        </tr>
        <tr>
            <td style="text-align:left"><label for="passwort">Passwort:</label></td>
            <td><input type="password" id="passwort" name="passwort" required="required"/></td>
        </tr>
        <tr>
            <td style="text-align:left">Benachrichtigungen über</td>
            <td><input type="checkbox" name="check1" value="check" checked="checked"/>Neue Folien</td>
        </tr>
        <tr>
        <td/>
            <td><input type="checkbox" name="check2" value="check" checked="checked"/>Neues Übungsblatt</td>
        </tr>
        <tr>
    <td/>
            <td><input type="checkbox" name="check3" value="check" checked="checked"/>Terminverschiebungen</td>
        </tr>

    </table>
    <br/>
        <button name="submitbutton" type="submit">Registrieren</button>


</form>
</body>
</html>
answer.html:

Code: Alles auswählen

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Anmeldebestätigung</title>
</head>
<body>
<h1>Anmeldebestätigung</h1>
<p>Hallo {{vorname}} {{nachname}},</p>
<p>vielen Dank für die Anmeldung zum Newsletter </p>
<p>Ihr Login lautet <span style="font-style: italic;">{{login}}</span></p>
<p>Sie haben sich registriert für: {{anmeldungen}}</p>
</body>
</html>
app.py:

Code: Alles auswählen

from flask import *

app = Flask(__name__)

@app.route('/')
def start():
   return redirect('index')

@app.route('/index')
def index():
    return render_template('index.html')

@app.route('/answer')
def answer():
    ausgabe=""
    if(request.args['check1']):
        check1 = "Folien"
        ausgabe += check1

    if (request.args['check2']):
        check2 = "Übungsblätter"
        ausgabe += ", "+check2

    if(request.args['check3']):
        check3 = "Termine"
        ausgabe += ", "+check3
  
    return render_template('answer.html', vorname=request.args['vorname'], nachname=request.args['nachname'], login=request.args['login'], anmeldungen=ausgabe)

Wäre sehr dankbar, wenn mir jemand weiterhelfen kann.

Vielen Dank im Voraus!
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

In deinem HTML Form müsste:

Code: Alles auswählen

<form method="post" action="{{ url_for('answer') }}">
und in deinen views:

Code: Alles auswählen

@app.route('/answer', methods=['POST'])
wenn ich mich nicht irre.

und würde in deinen views auch noch den post request separat abfangen, falls irgendwann noch ein get hinzukommt:

Code: Alles auswählen

@app.route('/answer', methods=['POST'])
def answer():
	if request.method == 'POST':
		(...) 
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@naheliegend: man kann auch Formulare per GET-Request senden, auch wenn das für so komplexe Formulare eher ungewöhnlich ist, vor allem, wenn damit der Zustand auf dem Server verändert wird, dann sollte man POST verwenden.

@kopra: Dein Problem ist, dass Du auf Schlüssel zugreifst, die gar nicht existieren (müssen). Das mußt Du per get absichern.
*-importe sind schlecht, importiere die Objekte die Du brauchst explizit.
if ist keine Funktion, die Klammern um die Bedingungen also unsinnig.
check1, check2 und check3 sind schlechte Namen. Warum nennst Du die Checkboxen nicht Folien, Übungsblätter und Termine?
Das Komma in ausgabe sieht komisch aus, wenn check1 nicht gesetzt ist, dafür nimmt man normalerweise Listen und join.
Auch die anderen Felder müssen nicht unbedingt gesetzt sein, nur weil Du das so im HTML angegeben hast. Das mußt Du auf jedenfall auf Serverseite auch prüfen und eine entsprechende Fehlermeldung zurückschicken.

Code: Alles auswählen

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def start():
   return redirect('index')

@app.route('/index')
def index():
    return render_template('index.html')

@app.route('/answer')
def answer():
    ausgabe = []
    for key, name in [('check1', 'Folien'), ('check2', 'Übungsblätter'), ('check3', 'Termine')]:
        if request.args.get(key):
            ausgabe.append(name)
  
    return render_template('answer.html',
        vorname=request.args['vorname'],
        nachname=request.args['nachname'],
        login=request.args['login'],
        anmeldungen=', '.join(ausgabe))
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

Danke für den Hinweis
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
kopra
User
Beiträge: 2
Registriert: Mittwoch 30. Dezember 2020, 15:38

@Sirius3

Vielen Dank für Deine Antwort. Es funktioniert jetzt.

Aber was meinst Du mit:?
Auch die anderen Felder müssen nicht unbedingt gesetzt sein, nur weil Du das so im HTML angegeben hast. Das mußt Du auf jedenfall auf Serverseite auch prüfen und eine entsprechende Fehlermeldung zurückschicken.
Meinst Du mit anderen Feldern, z.B. EMail-Adresse? Durch required="required" wird doch sichergestellt, dass dieses Feld nicht leer sein kann?
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kopra: Das wird vielleicht vom Browser sichergestellt wenn denn ein Browser und/oder das Formular verwendet wird. Benutzer machen aber die lustigsten Sachen. Keinen Browser verwenden zum Beispiel.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

@kopra: Also bei allen Daten die du serverseitig verwendest, musst du sicherstellen, dass diese auch vorhanden sind. Wenn die nicht vorhanden sind, musst du das dem Client zurückgeben. Kannst auch noch andere Dinge prüfen, z.B. die Länge oder ob die angegebene Mailadresse auch wirklich eine "valide" Mailadresse ist oder ob der Benutzer da "12345" reingeschrieben hat. Ich habe gerade heute genau das in Flask mit Flask-WTF implementiert. Geht echt gut und läuft. https://flask-wtf.readthedocs.io/en/sta ... start.html
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
Antworten