Dramal
Dramal

Reputation: 177

How do different Form objects communicate in Flask-wtforms?

A typical view is something like

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        # do stufff
        return redirect(url_for('somewhere_else', param=param))
    return render_template('login.html', form=form)

What I'm confused about: when the login() view is called, isn't a new LoginForm() instantiated with form = LoginForm()? How does this brand new form ever validate_on_submit()?

Upvotes: 2

Views: 157

Answers (2)

Bartosz Marcinkowski
Bartosz Marcinkowski

Reputation: 6861

Look at the source code of flask-wtf (I removed unrelated fragments and added comments):

class Form(SecureForm):

    # ...

    def __init__(self, formdata=_Auto, obj=None, prefix='', csrf_context=None,
                 secret_key=None, csrf_enabled=None, *args, **kwargs):

        # ...

        if formdata is _Auto:
            if self.is_submitted():
                formdata = request.form  # !!! LOOK HERE !!!
                if request.files:
                    formdata = formdata.copy()
                    formdata.update(request.files)
                elif request.json:
                    formdata = werkzeug.datastructures.MultiDict(request.json)
            else:
                formdata = None

        # ...

So, if you don't pass formdata explicitly to form's constructor and current request "is submitted" (the method is either PUT or POST), it uses the request.form.

Upvotes: 3

Doobeh
Doobeh

Reputation: 9440

It's addressed in the first page of the quick-start guide in the documentation:

Note that you don’t have to pass request.form to Flask-WTF; it will load automatically. And the convenience validate_on_submit will check if it is a POST request and if it is valid.

So when you instantiate the form, it'll automatically load in the existing request if it can.

Upvotes: 3

Related Questions