formsflaskroutes

Why does form stay in scope between route calls in flask?


Im going through the flask mega tutorial chapter 5 and realised there is a part I don't understand: The formvariable seems to stay in scope between calls to a route function, see below code (abbreviated from full example in chapter 5).

@app.route("/register", methods=["GET", "POST"])
def register():

    form = RegistrationForm()

    if form.validate_on_submit():
        #Add user to data base
        return redirect(url_for("login"))
    return render_template("register.html", title="Register", form=form)

My understanding is the following:

On first navigation to /register it is called with "GET". The formis instantiated and form.validate_on_submit()is falseso it return the form and the user fills it in.

When the user submits the form the /register route is called with "POST". In my mind the scope of the register() function from the last call should be lost, a new forminstantiated and form.validate_on_submitshould once again be falseand we would be stuck in a loop.

Debugging shows that it does not work this way though and my best understanding is that form somehow persists but I don't understand why/the mechanism via which it persists. Could someone enlighten me?


Solution

  • The first request is GET, so form.validate_on_submit() returns false, because form.is_submitted() or request.method checks whether it is a POST request.
    form.validate(), which checks the input, should therefore not be called at all.

    During the second call with POST, the entered form data from request.form and request.files are automatically adopted during the instantiation of the form. For this reason, form.validate_on_submit() is true as long as the input is valid.
    As long as the user is not redirected or the form data is set to none, it is retained. For security reasons, it only affects request.form and not request.files.