87 votes

Quelle est la cause de l'erreur de demande incorrecte lors de la soumission d'un formulaire dans une application Flask?

Après avoir lu de nombreux problèmes similaires et la documentation pertinente de Flask, je ne semble pas réussir à comprendre ce qui génère l'erreur suivante lors de la soumission d'un formulaire :

400 Bad Request

Le navigateur (ou le proxy) a envoyé une requête que ce serveur n'a pas pu comprendre.

Alors que le formulaire s'affiche toujours correctement, la mauvaise requête se produit lorsque je soumets un formulaire HTML qui est lié à l'une de ces fonctions :

@app.route('/app/business', methods=['GET', 'POST'])
def apply_business():
    if request.method == 'POST':    
        new_account = Business(name=request.form['name_field'], email=request.form['email_field'], account_type="business", 
            q1=request.form['q1_field'], q2=request.form['q2_field'], q3=request.form['q3_field'], q4=request.form['q4_field'], 
            q5=request.form['q5_field'], q6=request.form['q6_field'], q7=request.form['q7_field'],
            account_status="pending", time=datetime.datetime.utcnow())
        db.session.add(new_account)
        db.session.commit()
        session['name'] = request.form['name_field']    
        return redirect(url_for('success'))
    return render_template('application.html', accounttype="business")          

@app.route('/app/student', methods=['GET', 'POST'])
def apply_student():    
    if request.method == 'POST':    
        new_account = Student(name=request.form['name_field'], email=request.form['email_field'], account_type="student", 
            q1=request.form['q1_field'], q2=request.form['q2_field'], q3=request.form['q3_field'], q4=request.form['q4_field'], 
            q5=request.form['q5_field'], q6=request.form['q6_field'], q7=request.form['q7_field'], q8=request.form['q8_field'], 
            q9=request.form['q9_field'], q10=request.form['q10_field'],
            account_status="pending", time=datetime.datetime.utcnow())
        db.session.add(new_account)
        db.session.commit()
        session['name'] = request.form['name_field']    
        return redirect(url_for('success')) 
    return render_template('application.html', accounttype="student")

La partie pertinente de HTML est

    apply

    {% if accounttype=="business" %}

Le problème pour la plupart des gens n'était pas d'appeler GET ou POST, mais je le fais dans les deux fonctions, et j'ai vérifié deux fois pour m'assurer d'avoir importé tout ce qui est nécessaire, tel que from flask import request. J'ai également interrogé la base de données et confirmé que les ajouts du formulaire n'étaient pas ajoutés.

Dans l'application Flask, je demandais des champs de formulaire qui étaient étiquetés légèrement différemment dans le formulaire HTML. Garder les noms cohérents est essentiel. Plus d'informations peuvent être trouvées dans cette question Erreur d'envoi de formulaire, Flask

0 votes

0 votes

@SeanVieira J'ai; bien que cela cause la même erreur, le problème semblait survenir du fait qu'il essayait de soumettre un formulaire à partir de deux boutons différents sur la même page - le problème était de différencier entre les deux - alors que j'ai seulement un seul bouton appelant un POST.

6 votes

Chuckles Désolé, j'aurais dû être plus clair - "Flask lève une erreur HTTP lorsqu'il ne parvient pas à trouver une clé dans les dictionnaires args et form" - l'un des champs que vous essayez d'accéder dans request.form n'est pas là (par exemple, vous envoyez name_feild et cherchez name_field - notez la faute d'orthographe), d'où l'erreur. (Définir app.debug = True vous aidera à trouver l'erreur).

143voto

zch Points 2878

La solution était simple et a été découverte dans les commentaires. Comme indiqué dans cette question, Erreur d'envoi de formulaire, Flask, et souligné par Sean Vieira,

... le problème est que Flask génère une erreur HTTP lorsqu'il ne parvient pas à trouver une clé dans les dictionnaires args et form. Ce que Flask suppose par défaut, c'est que si vous demandez une clé particulière et qu'elle n'est pas présente, alors quelque chose a été omis de la requête et que la requête entière est invalide.

En d'autres termes, si seul un élément de formulaire que vous demandez en Python ne peut être trouvé dans le HTML, alors la requête POST n'est pas valide et l'erreur apparaît, dans mon cas sans aucune anomalie dans la trace de la pile. Pour moi, c'était un manque de cohérence dans l'orthographe : dans le HTML, j'ai étiqueté différents éléments de formulaire

tandis qu'en Python, lorsqu'un POST était appelé, je récupérais un formulaire inexistant avec

request.form['question1']

alors que, pour être cohérent avec les noms de mes formulaires HTML, il aurait dû être

request.form['question1_field']

12 votes

Vous pouvez également request.form.get('key', valeur_par_défaut)

1 votes

@OdraEncoded votre solution a résolu le problème. Je n'y avais pas pensé, mais dict.get() renvoie None, ce qui est plus sûr que d'accéder directement à la clé, ce qui peut provoquer une KeyError et donc faire planter l'appli.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X