2012-05-23 18 views
20

estoy usando matraz de WTF:matraz de WTF - validate_on_submit() nunca se ejecuta

Aquí es mi forma:

from flask.ext.wtf import Form, TextField 

class BookNewForm(Form): 
    name = TextField('Name') 

Aquí es el controlador:

@book.route('/book/new', methods=['GET', 'POST']) 
def customers_new(): 
    form = BookNewForm() 
    if form.is_submitted(): 
     print "submitted" 
    if form.validate(): 
     print "valid" 
    if form.validate_on_submit(): 
     flash("Successfully created a new book") 
     return redirect(url_for('.books_show')) 
    return render_template('views/books_new.html', form=form) 

Ahora el problema es que si miras los resúmenes de impresión, siempre se imprime enviado, pero NUNCA se imprime como válido y validate_on_submit() nunca se ejecuta. ¿Por qué?

Respuesta

31

No está insertando el campo CSRF en el formulario HTML.

<form method=post> 
    {{ form.csrf_token }} 
    {{ form.name }} 
    <input type=submit> 
</form> 

Después de añadir form.csrf_token a la plantilla (docs), la forma validará como se esperaba.

Agregue print(form.errors) después de validar el formulario para ver los errores que se produjeron. errors estará vacío antes de la validación. En este caso, hay un error por perder

@book.route('/book/new_no_csrf', methods=['GET', 'POST']) 
def customers_new_no_csrf(): 
    form = BookNewForm() 
    print(form.errors) 

    if form.is_submitted(): 
     print "submitted" 

    if form.validate(): 
     print "valid" 

    print(form.errors) 

    if form.validate_on_submit(): 
     flash("Successfully created a new book") 
     return redirect(url_for('.books_show')) 

    return render_template('books_new.html', form=form) 
{} 
submitted 
{'csrf_token': [u'CSRF token missing']} 
127.0.0.1 - - [29/May/2012 02:01:08] "POST /book/new_no_csrf HTTP/1.1" 200 - 
127.0.0.1 - - [29/May/2012 02:01:08] "GET /favicon.ico HTTP/1.1" 404 - 

I created an example on GitHub.

+4

¡Muchas gracias! ¡Este fue el problema exacto! No incluí el campo csrf en mi formulario. Intentar resolverlo con '{{form.csrf}}' no funcionó, pero al hacerlo: '{{form.hidden_tag()}}' resolvió el problema. También tenía razón acerca de la impresión de errores, ¡es bueno saber cómo funciona correctamente ahora! – kadrian

+1

Me alegra ayudar. Si está ejecutando WTForms 0.6 o posterior, 'form.csrf' se convirtió en' form.csrf_token', así que tenga cuidado, pero 'form.hidden_tag()' funciona igual de bien. –

+0

Esto me estaba dando pesadillas. Muchas gracias. – skjoshi

10

puede imprimir errores

print form.errors 

o

app.logger.debug(form.errors) 

y si tienes csrf de errores, se deben establecer form.csrf_token en su plantilla.

+1

gracias por esta sugerencia, pero no se imprime 'impresión form.errors' {} . Aún form.validate() devuelve False – kadrian

+0

Me preguntaba cómo se debería proceder para depurar los problemas de validación de formularios de Flask. Muy bien – jxramos

0

estaba limpiando la sesión frasco si no estaba inscrito antes de cada petición. Esto estaba causando este problema.

@main.before_request 
def before_request(): 
    if not current_user.is_authenticated(): 
     # TODO clean sessions may cause CSRF missing issue 
     session.clear() 
     print "Session Cleared" 
     return redirect(url_for('auth.login')) 
2

inserto esto después de la etiqueta en el archivo html plantilla:

{{ form.csrf_token }} 
0

me encontré con este cuando se trata de rendir un FormField que se repiten a lo largo de mi FieldList en mi plantilla. Tenía que incorporar dos elementos hidden_tag uno para la forma FieldList y uno para la forma FieldForm, buscar en los comentarios de la plantilla para la palabra clave "etiqueta oculta"

class ParamRangeForm(FlaskForm): 
    minX = FloatField() 
    maxX = FloatField() 

class ParamRangesForm(FlaskForm): 
    paramRanges = FieldList(FormField(ParamRangeForm)) 
    submit  = SubmitField('Submit') 

    def loadParams(self) : 
     for paramName in ["p1" , "p2" , "p3", "p4"] : 
      prf = ParamRangeForm() 
      prf.minX = -100.9#float('-inf') 
      prf.maxX = 100.5#float('-inf') 
      self.paramRanges.append_entry(prf) 

... 

    <form action="" method="POST" enctype="multipart/form-data"> 
    {{ rangesForm.hidden_tag() }} <!--#### HIDDEN TAG #1 --> 
    <table> 
     <!--Print Column Headers--> 
     <thead> 
     <tr> 
     <th class="ColumnHeader">Parameter</td> 
     <th class="ColumnHeader">Min</td> 
     <th class="ColumnHeader">Max</td> 
     </tr> 
     </thead> 

     <!--Print Parameter Rows--> 
     <tbody> 
     {% for paramRange in rangesForm.paramRanges %} 
     <tr> 
      {{ paramRange.hidden_tag() }} <!--#### HIDDEN TAG #2 --> 
      <td>p{{ loop.index }}</td> 
      <td>{{ paramRange.minX }}</td> 
      <td>{{ paramRange.maxX }}</td> 
     </tr> 
     {% endfor %} 
     </tbody> 
    </table> 
    </div> 
    {{ rangesForm.submit() }} 
    </form> 
Cuestiones relacionadas