Flacon wtf forme AttributeError: 'Demande' de l'objet n'a pas d'attribut 'POST'
Je viens de commencer le codage avec Flacon et je veux mettre en place CSRF sur un petit formulaire dans mon application. Je suis ce http://wtforms.readthedocs.org/en/2.0.2/csrf.html pour une session de mise en œuvre. J'ai regardé sur le web pour un bien que d'une solution à un problème similaire mais je n'ai eu aucun succès, toutes mes excuses si c'est une double question.
Problème avec ce code:
Lorsque je l'exécute dans l'environnement virtuel j'ai le trace de la pile avec AttributeError: 'Request' object has no attribute 'POST'
-
Objectif: mettre en œuvre csrf sur wtform instance
Environnement: wtf version 2.02, flacon de 0,10 venv avec python 2.7
Traceback (most recent call last):
File "/home/maria/Desktop/ciacicode/fci/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/home/maria/Desktop/ciacicode/fci/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/maria/Desktop/ciacicode/fci/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/maria/Desktop/ciacicode/fci/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/maria/Desktop/ciacicode/fci/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/maria/Desktop/ciacicode/fci/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/maria/Desktop/ciacicode/fci/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/maria/Desktop/ciacicode/fci/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
TypeError: fci_form() takes exactly 1 argument (0 given)
fci_form.py
from flask import session, request
from flask.ext.wtf import Form
from wtforms import TextField, validators, SubmitField
from wtforms.validators import Required, Length
from wtforms.csrf.session import SessionCSRF
from datetime import timedelta
import config # my config file
# create super class
class MyForm(Form):
class Meta:
csrf = True
csrf_class = SessionCSRF
csrf_secret = config.secret_key
csrf_time_limit = timedelta(minutes=20)
@property
def csrf_context(self):
return request.session
# create a class for the form
class postcodeInput(MyForm):
postcode = TextField('postcode',[validators.Required(message=(u"Where is your postcode?")),validators.Length(min=2, max=10)])
submit = SubmitField('Submit')
views.py
from flask import Flask, render_template, request, __version__, url_for, session, abort, flash, redirect
# importing the class called postcode_input
from fci_form import postcodeInput
import config
import fciUtils
#pdb.set_trace()
app = Flask(__name__)
app.debug = True
# Views of the app
@app.route('/')
def index():
return render_template('home.html')
@app.route('/fci', methods=['GET', 'POST'])
def fci_form():
error = None
form = postcodeInput(request.POST, meta={'csrf_context': request.session})
if form.validate_on_submit():
# handle user input
postcode = request.form['postcode']
# calculate fci
result = fciUtils.fciReturn(postcode)
return render_template('fci_form.html',form = form, result = result)
elif request.method == 'GET':
return render_template('fci_form.html', form = form)
else:
error = 'Enter a valid postcode'
return render_template('fci_form.html', form=form, error=error)
if __name__ == '__main__':
app.secret_key = config.secret_key
app.run(threaded=True)
Le modèle est fci_form.html dans le dossier/templates
{% extends 'layout.html' %}
{% block form %}
<section>
<header><h1>...</h1><br></header>
<form action="{{ url_for('fci_form')}}" method='POST'>
<p>Enter your London postcode:</p>
<section>
{% if error %}
<p class="error"><strong>Error: </strong>{{error}}</p>
{% endif %}
{{form.csrf_token}}
{{form.postcode}}
{{form.submit(class_="pure-button")}}
</section>
</form>
</section>
{% endblock %}
{% block result %}
<section>
<h4>{{result}}</h4>
</section>
{% endblock %}
Ce qui me manque ici?
OriginalL'auteur ciacicode | 2015-04-07
Vous devez vous connecter pour publier un commentaire.
Votre problème est que vous définissez votre
/fci
route:qui signifie que vous vous attendez à être passé en argument. Cependant, Flacon ne passe pas
request
via les arguments de la fonction, mais plutôt un un local de threadsdemande
de l'objet. Retirez simplement l'argument et l'importationrequest
deflask
à la place:def view(request): form = Registration(request.POST, meta={'csrf_context': request.session}) # rest of view here
Si vous regardez l'ensemble de la page, vous verrez que la documentation interrupteurs va-et-vient entre un mondial
request
objet (la Gourde) et unrequest
argument (à la Django et de la Pyramide). C'est plus de confusion que cela doit être pour les nouveaux arrivants, mais depuis WTForms essaie d'être cadre agnostique, il ne prend un sens qu'ils utilisent les deux approches dans leurs exemples.J'ai enlevé la demande en tant que paramètre, mais maintenant j'ai un autre type d'erreur:
AttributeError: 'Request' object has no attribute 'POST'
, j'ai mis à jour ma question d'origine de manière à refléter la situation actuelle. Veuillez noter que j'ai fait de demande d'importation de flacon dans l'views.pyPOST les paramètres sont fournis dans
request.form
, pasrequest.POST
, au moins en Flacon 🙂J'ai fini la mise à jour de wtf dans mon environnement virtuel et de l'importation au lieu de
flask.ext.wtf
une nouvelleflask_wtf
, qui a csrf activé par défaut. J'ai aussi réalisé que j'étais la définition de l'app secret de la clé après l'initialisation de l'application, provoquant même la dernière intégré csrf de la mise en œuvre de flast_wtf à l'échec. Merci pour votre aide.OriginalL'auteur Sean Vieira