Introduction to flask – (III) form submission

Time:2022-5-3

preface

In web applications,Form is widely usedFor example, user login, such as QQ login.This paper uses flask to implement a simple demo of form submission.

Final effect:

Introduction to flask - (III) form submission

image.png

testing environment

  • Ubuntu20.04/win11
  • Flask
  • VSCode

Implementation of flash form

General form implementation

In the form < / inuform > > tag definition, add the tag in the < form / inuform > >

    <form action="#" method="post">
        <div>
            <label for="username">Username</label>
            <input type="text" name="username" placeholder="input username">
        </div>
        <div>
            <label for="pwd">Password</label>
            <input type="text" name="pwd" placeholder="input password">
        </div>
        <input type="submit" value="submit">
    </form>

Implementation of form in flask

In flask, the above method is generally not used. Flask provides some extensionsFlask-WTFandwtforms, the operation of form form in flask is generally implemented by flask WTF.

pip install flask-wtf

wtformsProvides controls commonly used in form forms:

  • fields: StringField, PasswordField, BooleanField, SubmitFieldFor generating < input > tags
  • Validators: validator to verify whether the input is legal
    "DataRequired",
    "data_required",
    "Email",
    "email",
    "EqualTo",
    "equal_to",
    "IPAddress",
    "ip_address",
    "InputRequired",
    "input_required",
    "Length",
    "length",
    "NumberRange",
    "number_range",
    "Optional",
    "optional",
    "Regexp",
    "regexp",
    "URL",
    "url",
    "AnyOf",
    "any_of",
    "NoneOf",
    "none_of",
    "MacAddress",
    "mac_address",
    "UUID",
    "ValidationError",
    "StopValidation",

The flash WTF extension package provides a class:FlaskFormGenerally, custom forms inherit this flagform.
be careful: because the browser has the function of cookies, for the sake of the security of form submission, the CSRF token needs to be specified when the form is submitted, and it needs to be set in flagSECRET_KEY

app.config['SECRET_KEY'] = 'hello-flask'   # RuntimeError: A secret key is required to use CSRF.

SECRET_ The value of key is a random string.

Specific application steps of flask form:

  • Step1: custom form class, inheritanceFlaskForm
class LoginForm(FlaskForm):
    username = StringField(label='Username', validators=[DataRequired(), Length(1, 30)])
    password = PasswordField(label='Password', validators=[DataRequired(), Length(4, 10)])
    remember = BooleanField(label='Remember me')
    submit = SubmitField(label='Login')
  • Step 2: configure the view function, instantiate the form object, and pass the form object torender_template()function
    General form submissionPost requestTherefore, you need to set methods =’post ‘in the route
@app.route('/', methods=['GET', 'POST'])
def index():
    form = LoginForm()
    if form.validate_on_submit():
        global username
        global pwd
        username = form.username.data
        pwd = form.password.data
        #Redirect to get request
        return redirect((url_for('success')))
    return render_template('index.html', form=form)
  • Step 3: render the form in HTML and generate the form tag.
    For the sake of aesthetics and ease of use, the form is rendered using bootstrap flash.
    bootstrap: Twitter’s open source front-end framework provides bootstrap CSS and bootstrap mini. CSS, including the commonly used CSS styles, does not need to think too much about styles when developing.
    bootstrap-flask: a python extension of flask encapsulates bootstrap, which is used in the same way as bootstrap in HTML.

pip install bootstrap-flask

Use process of bootstrap flash:
Load the CSS file of bootstrap (CDN can be used to load directly here, or you can download it locally) – > Import using jinja2 syntaxrender_form()Macro function — > use render_ Form() renders the incoming form object.

   {{ bootstrap.load_css() }}
   {% from 'bootstrap/form.html' import render_form  %}

    <main>
        {{ render_form(form=form, form_type="basic") }}
        {{ bootstrap.load_js() }}
    </main>

About render_ Form() macro function:

{# valid form types are "basic", "inline" and "horizontal" #}
{% macro render_form(form,
                    action="",
                    method="post",
                    extra_classes=None,
                    role="form",
                    form_type="basic",
                    horizontal_columns=('lg', 2, 10),
                    enctype=None,
                    button_map={},
                    button_style="",
                    button_size="",
                   ,
                    novalidate=False,
                    render_kw={}) %}

Test Engineering

directory structure

The file directory structure is very simple. It does not contain CSS / JS files, only HTML templates.

Introduction to flask - (III) form submission

image.png

code implementation

  • app.py
from flask import Flask, render_template, url_for, redirect, flash
from flask_bootstrap import Bootstrap
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from flask_wtf import FlaskForm
from wtforms.validators import DataRequired, Length

# https://bootstrap-flask.readthedocs.io/en/latest/

class LoginForm(FlaskForm):
    username = StringField(label='Username', validators=[DataRequired(), Length(1, 30)])
    password = PasswordField(label='Password', validators=[DataRequired(), Length(4, 10)])
    remember = BooleanField(label='Remember me')
    submit = SubmitField(label='Login')


app = Flask(__name__)
app.config['SECRET_KEY'] = 'hello-flask'   # RuntimeError: A secret key is required to use CSRF.
Bootstrap = bootstrap (APP = APP) # initialize bootstrap

username = None
pwd = None

@app.route('/login_success')
def success():
    flash(message=username)
    flash(message=pwd)
    return render_template('success.html')


@app.route('/', methods=['GET', 'POST'])
def index():
    form = LoginForm()
    if form.validate_on_submit():
        global username
        global pwd
        username = form.username.data
        pwd = form.password.data
        #Redirect to get request
        return redirect((url_for('success')))
    return render_template('index.html', form=form)
app.run()
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>flask_form</title>
    {{ bootstrap.load_css() }}
    {% from 'bootstrap/form.html' import render_form  %}
</head>
<body>
    <main>
        {{ render_form(form=form, form_type="basic") }}
        {{ bootstrap.load_js() }}
    </main>
</body>
</html>
  • success.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>flask_form</title>
    {{ bootstrap.load_css() }}
</head>
<body>
    <main>
        {% for message in get_flashed_messages() %}
            {{ message }}
        {% endfor %}
        {{ bootstrap.load_js() }}
    </main>
</body>
</html>

Operation results:

Introduction to flask - (III) form submission

image.png
Introduction to flask - (III) form submission

image.png

Observe the HTML generated by bootstrap flash, open the browser debugging window and you can see the HTML code:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>flask_form</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
    
</head>
<body>
    <main>
        
    <form action="" method="post"
            role="form">
        <input name="csrf_token" type="hidden" value="IjZiYzNjZTFiODg3NTA3OTBjMmNiYmI1ODBjYjkwODM4MWQxYWI3NGYi.Yfa-Xg.Fg_26W5499T3niSfJzvmdvIA_w8">
    <div>
        <label for="username">Username</label>
        <input maxlength="30" minlength="1" name="username" required type="text" value="">      
    </div>
    <div>
        <label for="password">Password</label>
       <input maxlength="10" minlength="4" name="password" required type="password" value="">       
    </div>
        
    <div><input name="remember" type="checkbox" value="y">
        <label for="remember">Remember me</label>
    </div>
    <input name="submit" type="submit" value="Login">
    </form>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous"></script>
    </main>
</body>
</html>
  1. Render of bootstrap flash_ The form() macro function will be added automatically when the form is renderedCSRF token<input name="csrf_token" type="hidden" value="IjZiYzNjZTFiODg3NTA3OTBjMmNiYmI1ODBjYjkwODM4MWQxYWI3NGYi.Yfa-Xg.Fg_26W5499T3niSfJzvmdvIA_w8">

  2. When the default CDN is adopted, bootstrap flash will be loaded automaticallyjquery.js, popper.js, bootstrap.min.jsThese three JavaScript