Giter Site home page Giter Site logo

wtforms / flask-wtf Goto Github PK

View Code? Open in Web Editor NEW
1.5K 31.0 310.0 1.13 MB

Simple integration of Flask and WTForms, including CSRF, file upload and Recaptcha integration.

Home Page: https://flask-wtf.readthedocs.io

License: BSD 3-Clause "New" or "Revised" License

Python 100.00%
python flask wtforms html flask-wtf forms

flask-wtf's Introduction

flask-wtf's People

Contributors

ajford avatar azmeuk avatar bacher09 avatar crast avatar dalepotter avatar davidism avatar dependabot[bot] avatar dosenpfand avatar dplepage avatar fanzeyi avatar floer32 avatar fsouza avatar git-commit avatar greyli avatar jarus avatar jocelyndelalande avatar jugmac00 avatar lepture avatar lipis avatar martinmaillard avatar mgraupner avatar nfvs avatar nickjj avatar pre-commit-ci[bot] avatar rduplain avatar sbraz avatar sloria avatar techniq avatar tonyseek avatar twolfson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flask-wtf's Issues

WTForms: Error Handling for Forms in Templates

In the WTForms' documentation on displaying errors it gives an example of putting all of a form's errors in a neat little section (second example) but when I run the aforementioned code Flask returns:

ValueError
ValueError: too many values to unpack

I imagine it comes from this line:

{% for field_name, field_errors in form.errors if field_errors %}

Is their example Django specific or am I just missing something?


Please make Form.hidden_tag() look at the widget type

Form.hidden_tag(), by default, iterates over all fields of the type HiddenField. This is wrong, as the canonical way to create a hidden integer field is:

myfield = IntegerField(widget=HiddenInput())

which does not result in a HiddenField. There are other use cases where a field can be made hidden with widget=HiddenInput(), e.g. I use it with SelectField to gain validation of a hidden field against a list of predefined values for free.

So, please look at the widget type, not the field type, when deciding which fields to put into the hidden div by default.

Missing/Inconsistent imports

Since this project imports "everything" from WTForms, it should import everything, not just some of the things. Or better drop importing anything and let the user decide. With the current design you need to update the imports every time something changes in WTForm. That makes this project hard to maintain.

As an example: In the init.py file you import SQL Alchemy ext (if its installed), but you don't import everything from this extension. SQL Alchemy validators.py are missing. This leaves the us with a situation were we have to guess what is imported by the flask-wtf ext and what has to be imported directly from WTForms.

I know this design decision is not made by the current project maintainer, but it should be re-evaluated to find a better solution.

FieldList FormField problem with data field named as 'description'

When I create a Field list of sub forms FieldList(FormField(myform)) I encounter a strange behaviour. If I have a data field named 'description' in the sub forms they are ignored i.e when rendering form fields in the view's template.

However, if I rename the data field to 'desc' or 'descriptionb' in the code and database it works fine. Also if I add a field of the name 'description' to the parent form and database instead that also works fine. So the problem seems isolated around the FieldList FormField

I ,therefore, wonder if the FieldList FormField scenero created some sort of reserved word (e.g. a method) which is causing the issue?

map form values back to model

It would be useful to map form values back to a model.

e.g.:

db = SQLAlchemy(app)

if form.validate_on_submit():
flash('success!')
form.save(db)

Bug with RecaptchaField and Flask-babel

If Flask-babel is installed but not used and not configured in the app, when a RecaptchaField is used in the template, you get an exception like the following:

  File "/Users/dimilia/Sites/wrk/adslabs-beer/adsabs/modules/feedback/templates/feedback_macro.html", line 47, in template
    {{ form.recaptcha() }}
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/wtforms/fields/core.py", line 140, in __call__
    return self.widget(self, **kwargs)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/flask_wtf/recaptcha/widgets.py", line 68, in __call__
    'visual_challenge':    _('Get a visual challenge'),
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/flaskext/babel.py", line 456, in gettext
    t = get_translations()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/flaskext/babel.py", line 194, in get_translations
    translations = support.Translations.load(dirname, [get_locale()])
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/flaskext/babel.py", line 209, in get_locale
    babel = ctx.app.extensions['babel']
KeyError: 'babel'

My installation is the following:

pip-2.6 freeze | grep -i flask
Flask==0.9
Flask-Babel==0.8
Flask-Cache==0.6.0
Flask-DebugToolbar==0.8.0
Flask-Login==0.1.3
Flask-Mail==0.7.6
Flask-MongoAlchemy==0.5.4
Flask-Pushrod==0.1.2
Flask-SQLAlchemy==0.16
Flask-Script==0.5.3
Flask-Testing==0.4
Flask-Uploads==0.1.3
Flask-WTF==0.8.3

Thanks!

validate_csrf() causes inconsistent behaviour when calling validate() twice

When calling validate_csrf() on the base Form class the form field is reset with the new token (and the token added to the session). The old session is removed so no token can be used twice.

This works fine, however it causes an inconsistent behaviour if validate() is called twice. This is because the current value of form.data is compared to the current session value, which in this case will always be True after the first call to validate().

While it is unnecessary (and inadvisable) to call validate() twice in a request, behaviour should be consistent.

In order to get round this there needs to be a flag which checks if the CSRF has been checked and validated.

How to reproduce:

class MyForm(Form):
    pass

@app.route("/", methods=("POST",))
def submit():
    form = MyForm() # form with csrf validation, but csrf not passed in POST
    assert not form.validate()
    assert not form.validate()  # breaks with AssertionError

CSRF seems broken with encapsulated form (FormField)

It seems multiple csrf tokens are generated when using a FormField to encapsulate one form with in another. I think the csrf token should only be inserted into the top level form, the encapsulated form should be ignored. But that might not be easy since the inner form looks like any other to Flask-WTF.

Maybe I missed something obvious or perhaps this is just a documentation issue.

To get around this, I imported BaseForm from flaskext.wtf and used that base class for the inner form... maybe there is a better way.


TypeError: html_params() keywords must be strings

When i trying display form in template, I receive an error
TypeError: html_params() keywords must be strings

form code

from flask.ext.wtf import Form, TextField, TextAreaField, IntegerField, SelectField, BooleanField, validators
from models import Pages
from application import babel

class PagesAdminForm(Form):
    PARENTS = ()
    PARENTS += (('', '_____________'),)
    for page in Pages.query.filter_by(is_group=True):
        PARENTS += (('%s' % (page.id), page.title),)

    title = TextField('Title', validators=[
        validators.Length(min=4, max=255),
        validators.Required()])
    slug = TextField('Slug')
    parent = SelectField('Parent', choices=list(PARENTS))
    is_group = BooleanField('Is group')

views

def create_page():
    form = PagesAdminForm()
    if form.validate_on_submit():
        page = Pages(title=form.title, slug=form.slug, is_group=form.is_group)
        db.session.add(page)
        db.session.commit()

    return render_template('admin/create_page.html', form=form)

template

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<form method="POST" action="">
    {{ form.csrf_token }}
    <dl>

    </dl>
    <p><input type="submit" value="Save"></p>
</form>
</body>
</html>

some documentation suggestion

Hello,

First of all, thanks for making flask-wtf, it has helped a lot!

After using it, I have some feedback on the documentation of things that could be improved:

  • a working example at the top of the documentation would be cool (much like flask home page)
  • there is not mentions of error handling (stuff like form.field_name.errors or form.errors)
  • there is not list of validators neither instructions on how to build custom ones
  • there is not instructions on how to build a custom field type
  • a lot of field types aren't listed
  • there is very few informations on how to use a form in a template except one small snippet nor how to customized field display

Hope this can help,

Kind regards,

Python 3

Python 3 support. Things to do:

  • remove Flask-Testing, since it doesn't support Python 3
  • Babel is not python3 compatible
  • wtforms is not python3 compatible
  • Flask-Uploads is not python3 compatible

Improve API changes (csrf/csrf_token)

Changing the API is sometimes necessary, but you should try to keep disruption low. A few notes for this and upcoming changes:

  • deprecate the old API before removing it
  • document the change, not only the new version but what actually changed
  • update the hosted documentation (the current one is outdated)

Anyway, thanks for making flask-wtf. Keep up the good work.

FieldList(FileField) does not follow request.files

When form data is passed to a FieldList, each key in the form data
dict whose prefix corresponds to the encapsulate field's name results
in the creation of an entry. This allows for the addition of new field
entries on the basis of submitted form data and thus dynamic
field creation. See:
http://groups.google.com/group/wtforms/browse_thread/thread/824e95123e38c697/4bc8cd59a84ea5f9

However, when the encaspulated field is a FileField, the FieldList
will not create entries according to the submitted form data. The
following will fail on the last assertion:

from flask import Flask, request
from StringIO import StringIO
from flaskext.wtf import Form, FieldList, TextField, FileField

app = Flask(__name__)
app.config['SECRET_KEY'] = 'SECRET'

# given this
class BrokenForm(Form):
    text_fields = FieldList(TextField())
    file_fields = FieldList(FileField())

text_data = [('text_fields-0', 'First input'),
             ('text_fields-1', 'Second input')]

file_data = [('file_fields-0', (StringIO('contents 0'), 'file0.txt')),
             ('file_fields-1', (StringIO('contents 1'), 'file1.txt'))]


with app.test_request_context(method='POST',
                                data=dict(input_data + file_data)):
    assert len(request.files) # the files have been added to the
                              # request

    f = BrokenForm(csrf_enabled=False)

    if f.validate_on_submit():
        assert len(text_data) == len(f.text_fields) # this succeeds
        assert len(file_data) == len(f.file_fields) # this doesn't!

This occurs because there is no overlap between the fields stored in
request.files and those in request.form, and Flask-WTF only looks at
request.form. The existing MultipleFileUpload test case didn't catch
this because it sets its FieldList's min_entries to 3; this means 3
FileFields exist that happen to correspond to what's in request.files
before that data is even processed. (These are created in the final
while loop in FieldList.process(*args), wtforms/fields.py; we're
failing in the 'if formdata:' block)

A simple solution is to combine request.form and request.files when
the latter exists and have the form process the result; the first
attached patch does just that.

This seems less than ideal, though, because it removes the distinction
between forms and files imposed by Werkzeug and thus might run counter
to sane assumptions. Furthermore, it combines the two whenever
request.files is present, not just when a FieldList encapsulates a
FileField. The second patch addresses these problems by introducing a
subclass of FieldList that processes request.files when its
encapsulated field is a FileField.

The third patch provides a test that ensures FileFields are added to
FieldLists on the basis of submitted data.

Finally, this is not strictly a problem with flask-wtf, but rather a
problem that will exist with anything that's based on Werkzeug and
uses wtforms. Perhaps there ought to be a werkzeug-wtf?


csrf field trickles into populate_obj

csrf is defined as standard HiddenField, which means that calling form.populate_obj(dbrecord) will insert 'csrf' value into the db record.

csrf should be defined with a class whose populate_obj() method does nothing - such as this

#!python

class InternalField(HiddenField):
    def populate_obj(self, obj, name):
        pass

CSRF / reset_csrf documentation when process 2 forms in single view

Assume I have a view like this):

#!python

def myview():
    form1 = FormOne()
    if form1.validate_on_submit():
        form2 = FormTwo()
        return render_template("template.html", form=form2)
    return do_something_else()

When form1 is processed in validate_on_submit(), the session is updated with a new csrf token. Upon instantiation of FormTwo, csrf_token variable in flaskext.wtf.Form.init is set to the new value (checked with print statement) BUT that new value is not present in form2 afterward - the old value is sticking around causing invalid csrf tokens when form2 is submitted.

I'm not sure how reset_csrf() factors into this... the way I finally got it working was to do this:

#!python

form2 = FormTwo()
form2.csrf.data = form2.csrf_reset()

Not sure I found any good examples of csrf_reset in the docs. Might be a problem between keyboard and chair over here but this just does not feel quite right.

Cheers.


Unwanted (and visibly labeled) csrf field in Form constructed of forms using FormField encapsulation

I'm dynamically constructing form, many of the building blocks are forms that get encapsulated in the Form as FormFields: e.g.:

 class EmailAddressForm(Form):
    email_address = TextField("email address", validators = [Email(message=(u'That\'s not a valid email address.'))] )

then called when constructing the form:

def email(self):
        return FormField(EmailAddressForm)

Note: adding csrf_enabled=false to addressform above is an error: TypeError: 'EmailAddressForm' object is not callable

so when the form is constructed and displayed, I get (excuse the mess, but really obnoxious id's removed)

<table id=""><tr><th><label for="-csrf_token">Csrf Token</label></th><td><input id="-csrf_token" name="-csrf_token" type="hidden" value="20121004121155##f2c748b3ab4113f19eed02cdb8bfe977aca840ec"></td></tr><tr><th><label for="-email_address">Email Address</label></th><td><input id="-email_address" name="n3j0e3_221a89d0f0d3af2c-email_address" type="text" value=""></td></tr></table></div>

Which you can see a csrf token, which is unneeded in the the sub-form. Is there a way to turn this off other than the documented way, why am I getting this? The csrf for the primary form itself works well (so far), and if i pass in (csrf_enabled=False) to the main form, there is no error -- there seems to be no way to turn off csrf in FormFields constructed from Form

tried so far:

 class EmailAddressForm(Form(csrf_enabled=false)):
    email_address = TextField("email address", validators = [Email(message=(u'That\'s not a valid email address.'))] )

is a RuntimeError('working outside of application context')

def email(self):
        return FormField(EmailAddressForm, csrf_enabled=False)

returns an TypeError: init() got an unexpected keyword argument 'csrf_enabled'

def email(self):
        return FormField(EmailAddressForm(csrf_enabled=false))

Note: adding is an error: TypeError: 'EmailAddressForm' object is not callable

CSRF_ENABLED = False in settings -- Still get the csrf field :/

visual: http://imgur.com/Dhfj7

0.8.4 not updated to PyPi?

PyPi doesn't seem to have been updated to 0.8.4, although it seems to be considered a dated actual release? There isn't a 0.8.4 tag either, although there is one for 0.8.3.

Travis and Coverage

Enable travis for flask-wtf and check coverage.

The current coverage of this package is:

..........................
Name                             Stmts   Miss  Cover   Missing
--------------------------------------------------------------
flask_wtf                           38      2    95%   17-18
flask_wtf.file                      27      1    96%   18
flask_wtf.form                      66      8    88%   12-13, 61, 72, 75, 78, 121, 136
flask_wtf.html5                      5      0   100%
flask_wtf.i18n                      39     11    72%   16, 37, 41-50, 58
flask_wtf.recaptcha                  4      0   100%
flask_wtf.recaptcha.fields          10      2    80%   16-17
flask_wtf.recaptcha.validators      38     27    29%   26, 29-38, 43-73
flask_wtf.recaptcha.widgets         32     19    41%   6-7, 16-17, 37, 46-82
--------------------------------------------------------------
TOTAL                              259     70    73%
----------------------------------------------------------------------
Ran 26 tests in 0.810s

Can't access form.data without csrf_token

As Form indirectly inherits from wtforms.ext.csrf.SecureForm, the data property always tries to access a 'csrf_token' field, which may not be there if CSRF_ENABLED is set to false. This causes any access to fail with KeyError: 'csrf_token' in wtforms/ext/csrf/form.py", line 50, in data. (Source)

self.validate() does nothing

WTForms 1.0.1

form.py, line 119: return self.is_submitted() and self.validate()

SessionSecureForm has no validate()

Recaptcha SSL API has changed

According to this announcement:

http://groups.google.com/group/recaptcha/browse_thread/thread/57baacc2a067035a/ea0303e7d7a49262

The URL for Recaptcha over SSL has changed from https://api-secure.recaptcha.net to https://www.google.com/recaptcha/api.

The SSL certificate for the old URL is no longer valid, so browsers will refuse to display recaptcha. The URL is hardcoded in flaskext/wtf/recaptcha/widgets.py.


Form data aren't set properly for form with one checkbox

Hi,
I have this problem:
I have a form, that only contains one checkbox. AFAICS when I uncheck the checkbox, then the POST request doesn't contain any data about it, just the csrf token. So far, so good. Now when I'm testing my app and I turn off csrf token, the post request is completely empty. That seems to cause the form to still return true for the checkbox data.
Am I doing something wrong or this a real issue?

Thanks.

from flask.ext.wtf import * raises Exception

Trying that will raise:

Traceback (most recent call last):
File "", line 1, in
TypeError: Item in ``from list'' not a string

But doing

from flask.ext.wtf import Form

works fine. This is using Flask 0.9, WTForms 1.0.2 and Flask-WTF 0.8 on Debian 6 with python 2.6.

Doing

from flask.ext.wtf import *

on Windows 7 with Python 2.7 does work, though.

Forms should distinguish which one was submitted

I have a page with two forms, one contains two checkboxes and the other some text inputs. I construct each form with data from DB, e.g. the checkboxes are sometimes preselected.
When I submit the other form, then the form with the checkboxes thinks that it has been submitted too (the form.is_submitted() only looks at request and checks that its post or put).
Therefore both checkboxes are set unchecked, as the form thinks that it has been submitted, but no data for the checkboxes are found (=> which means that the checkboxes get prefilled with False).

CSRF fails if there are only FileFields in the form

In <<changeset 119448003262>>, a change was introduced to make CSRF validation only happen if there was formdata. However, for a form with only a FileField, this change seems to cause CSRF validation to fail. Maybe it would make sense for validation to be skipped when there is no formdata -- //maybe// -- but it shouldn't fail.

An example form:

#!python
class UploadForm(wtf.Form):
    sheet = wtf.FileField('Character Sheet')
    submit = wtf.SubmitField("Upload")

Perhaps there should be a configurable setting for whether or not forms without formdata should be CSRF validated?


Bug when loading json data into TextFields

I'm writing a simple API that receives data via JSON. It takes that data, loads it via the json module into a native Python object, then passes it into the form constructor.

When I do this using a form defined via Flask-WTF, the TextFields have no data. When I do it via vanilla WTForms, everything works as expected.

I've attached a test file that should demonstrate what I'm talking about. It contains two simple forms, both with one field. One form uses flaskext.wtf, the other uses wtforms. I have tests both with and without csrf enabled.


Problem with importing wtforms inside html5.py file

I'm doing blog application to learn Python and Flask and I would like to launch it on Google App Engine. Unfortunately I have small problem with importing WTForms to the application. I'm currently using Flask 0.9, WTForms 1.0.1 and Flask-WTForms 0.8. I've added flaskext_wtf folder to root path of my project but I'm getting error from html5.py file.

[code]
File "/Users/lucas/Workspace/blog/flask_wtf/html5.py", line 1, in
from wtforms import TextField
File "/Users/lucas/Workspace/blog/flask/exthook.py", line 86, in load_module
raise ImportError('No module named %s' % fullname)
ImportError: No module named flask.ext.wtf.wtforms
It looks like it tries to find wtforms inside the extension path instead of my project path. How can I inform the html5.py file to look for the wtforms in the root?[/code]

Here are sources of my project - https://bitbucket.org/lucas_mendelowski/wblog/src

Can't handle unicode in forms

If you use unicode in forms, you get things like these:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 10: ordinal not in range(128)

This should likely be handled more properly.

ImportError: cannot import name ModelSelectField in flaskext/wtf/__init__.py

File "forms.py", line 1, in
from flaskext import wtf
File "/usr/lib/python2.7/site-packages/flaskext/wtf/init.py", line 78, in
from wtforms.ext.sqlalchemy.fields import QuerySelectField,
ImportError: cannot import name ModelSelectField

my pacakges:
Flask==0.6.1
Flask-SQLAlchemy==0.9.1
Flask-WTF==0.5
Jinja2==2.5.5
SQLAlchemy==0.6.6
WTForms==0.6.2
Werkzeug==0.6.2
distribute==0.6.14
git-remote-helpers==0.1.0
mercurial==1.7.3
vboxapi==1.0
wsgiref==0.1.2


Add file validators

Add a set of file upload validators to use with a FileField. These might be added in a separate subpackage. Validators could include:

  • is_file : check if field has a "file" attribute
  • allow_types/deny_types : allow/deny certain content types, e.g. "image/jpeg", "text/html" etc.
  • allow_filenames/deny_filenames : allow/deny certain filename patterns, e.g. ".jpg", ".txt" etc.
  • is_image : checks that content type and filename match valid image (JPEG, GIF, TIFF, PNG).
  • is_audio: checks that content type and filename match valid audio file (WAV, OGG etc)

Push HTML5 to wtforms

Nothing about this module is flask specific - we should contribute this to wtforms.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.