Flask-WTF SelectField with CSRF protection enabled


Question

I'm having a problem when submitting a form containing a dynamically populated SelectField. For some reason when Flask tries to validate the CSRF token it always fails when the SelectField is in the form. When I remove the SelectField from the form, it validates the CSRF token successfully.

Has anyone come across this behavior?

EDIT

Form:

class AddToReportForm(Form):
    selectReportField = SelectField(u'Reports',choices=[('test1','test')])

    def __init__(self, *args, **kwargs):
        """
        Initiates a new user form object
        :param args: Python default
        :param kwargs: Python default
        """
        Form.__init__(self, *args, **kwargs)




    def validate(self,id_list):
        rv = Form.validate(self)

        if not rv:
            print False
            #Check for the CSRF Token, if it's not there abort.
            return False

        print True
        return True

Jinja2:

<form  method=post name="test">
{{ form.hidden_tag()}}




    {{ form.selectReportField }}
    <a href="#" onclick="$(this).closest('form').submit()" class="button save">Add to report</a>

</form>

Rendering:

form = AddToReportForm()
return render_template('random',title='add reports',form=form
1
2
5/29/2013 1:06:45 PM

Accepted Answer

I still can't see any connection between SelectField and CSRF. The validate method is little suspicious and the extra argument would trip the following testcase, but as it stands this seems to work just fine:

from flask import Flask, render_template_string
from flaskext.wtf import Form, SelectField

app = Flask(__name__)
app.debug = True
app.secret_key = 's3cr3t'


class AddToReportForm(Form):
    selectReportField = SelectField(u'Reports', choices=[('test1', 'test')])


@app.route('/test', methods=['GET', 'POST'])
def test():
    form = AddToReportForm()
    if form.validate_on_submit():
        print 'OK'
    return render_template_string('''\
<form method=post name="test">
{{ form.hidden_tag()}}
{{ form.selectReportField }}
<input type="submit">
</form>
''', form=form)


app.run(host='0.0.0.0')
2
5/29/2013 4:33:23 PM

Where are you setting SECRET_KEY? It must be available either in the Form class:

class AddToReportForm(Form):
    selectReportField = SelectField(u'Reports',choices=[('test1','test')])
    SECRET_KEY = "myverylongsecretkey"

    def __init__(self, *args, **kwargs):
        """
        Initiates a new user form object
        :param args: Python default
        :param kwargs: Python default
        """
        Form.__init__(self, *args, **kwargs)
    def validate(self,id_list):
        rv = Form.validate(self)

        if not rv:
            print False
            #Check for the CSRF Token, if it's not there abort.
            return False
        return True

or in the application bootstrap:

app = Flask(__name__)
app.secret_key = 'myverylongsecretkey'

or in the constructor:

form = AddToReportForm(secret_key='myverylongsecretkey')
return render_template('random',title='add reports',form=form)

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon