Flask signal and wtforms one, signal two, use of wtforms component

Flask signal and wtforms one, signal two, use of wtforms component

1. Signal

1.1. All built-in signals

request_started = _signals.signal('request-started') # Execute before request arrives
request_finished = _signals.signal('request-finished') # Execute after the request
 
before_render_template = _signals.signal('before-render-template') # Execute before template rendering
template_rendered = _signals.signal('template-rendered') # Execute after template rendering
 
got_request_exception = _signals.signal('got-request-exception') # Execute when the request execution is abnormal
 
request_tearing_down = _signals.signal('request-tearing-down') # Automatically execute after the request is executed (regardless of success or failure)
appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# Automatic execution after the request context is executed (regardless of success or failure)
 
appcontext_pushed = _signals.signal('appcontext-pushed') # Execute when requesting context push
appcontext_popped = _signals.signal('appcontext-popped') # Execute when requesting context pop
message_flashed = _signals.signal('message-flashed') # When flask is called to add data, it will be triggered automatically

1.2. Simple example of signal

The signals in the Flask framework are based on blinker, which mainly allows developers to customize some user behaviors during the Flask request process. First install blinker

pip install blinker
from flask import Flask,signals

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

def func(*args,**kwargs):
    print('Trigger signal', args, kwargs)
signals.request_started.connect(func)

@app.route('/')
def index():
    print('hello')
    return'hello world'

if __name__ =='__main__':
    app.run()

operation result:

2. the use of wtforms components

2.1. Installation

WTForms is a form component that supports multiple web frameworks. It is mainly used to verify user request data. installation method

pip install wtforms

2.2. User login

 When the user logs in, verify the user name and password

(1) app.py

from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets

app = Flask(__name__, template_folder='templates')
app.debug = True


class LoginForm(Form):
    name = simple.StringField(
        label='Username',
        #Custom Validation Rules
        validators=[
            validators.DataRequired(message='Username cannot be empty.'),
            validators.Length(min=6, max=18, message='User name length must be greater than %(min)d and less than %(max)d')
        ],
        #Page display plugin
        widget=widgets.TextInput(),
        #Add attributes
        render_kw={'class':'form-control'}
    )

    pwd = simple.PasswordField(
        label='Password',
        validators=[
            validators.DataRequired(message='The password cannot be empty.'),
            validators.Length(min=8, message='User name length must be greater than %(min)d'),
            #Regular expression
            validators.Regexp(regex="^(?=.*[az])(?=.*[AZ])(?=.*\d)(?=.*[$@$!%*?&]) [A-Za-z\d$@$!%*?&]{8,}",
                              message='The password must be at least 8 characters, at least 1 uppercase letter, 1 lowercase letter, 1 number and 1 special character')

        ],
        widget=widgets.PasswordInput(),
        render_kw={'class':'form-control'}
    )

@app.route('/login', methods=['GET','POST'])
def login():
    if request.method =='GET':
        form = LoginForm()
        return render_template('login.html', form=form)
    else:
        form = LoginForm(formdata=request.form)
        if form.validate():
            print('The data submitted by the user passes the format verification, and the submitted value is:', form.data)
        else:
            print(form.errors)
        return render_template('login.html', form=form)

if __name__ =='__main__':
    app.run()

(2) login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Login</h1>
<form method="post">

    <p>{{form.name.label}} {{form.name}} {{form.name.errors[0] }}</p>

    <p>{{form.pwd.label}} {{form.pwd}} {{form.pwd.errors[0] }}</p>
    <input type="submit" value="Submit">
    
</form>
</body>
</html>

Incorrect username and password format

2.3. User registration

(1) app.py

from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets

app = Flask(__name__, template_folder='templates')
app.debug = True



class RegisterForm(Form):
    name = simple.StringField(
        label='Username',
        validators=[
            validators.DataRequired()
        ],
        widget=widgets.TextInput(),
        render_kw={'class':'form-control'},
        default='derek'
    )

    pwd = simple.PasswordField(
        label='Password',
        validators=[
            validators.DataRequired(message='The password cannot be empty.')
        ],
        widget=widgets.PasswordInput(),
        render_kw={'class':'form-control'}
    )

    pwd_confirm = simple.PasswordField(
        label='Repeat password',
        validators=[
            validators.DataRequired(message='Repeated password cannot be empty.'),
            #EqualTo: Be the same as that field
            validators.EqualTo('pwd', message="The two password entries are inconsistent")
        ],
        widget=widgets.PasswordInput(),
        render_kw={'class':'form-control'}
    )

    email = html5.EmailField(
        label='Mailbox',
        validators=[
            validators.DataRequired(message='Mailbox cannot be empty.'),
            validators.Email(message='Mailbox format error')
        ],
        widget=widgets.TextInput(input_type='email'),
        render_kw={'class':'form-control'}
    )

    #RadiField单选
    gender = core.RadioField(
        label='Gender',
        choices=(
            (1,'Male'),
            (2,'Female'),
        ),
        coerce=int #Because the data submitted in the previous paragraph is in the str format, such as "1", "2", here is converted to int
    )
    #Single-selection drop-down box
    city ​​= core.SelectField(
        label='City',
        choices=(
            ('bj','Beijing'),
            ('sh','Shanghai'),
        )
    )
    #Multiple selection drop-down box
    hobby = core.SelectMultipleField(
        label='Hobbies',
        choices=(
            (1,'Basketball'),
            (2,'football'),
        ),
        coerce=int
    )

    favor = core.SelectMultipleField(
        label='Preferences',
        choices=(
            (1,'Basketball'),
            (2,'football'),
        ),
        widget=widgets.ListWidget(prefix_label=False),
        option_widget=widgets.CheckboxInput(), #Multiple choice
        coerce=int,
        default=[1, 2]
    )

    def __init__(self, *args, **kwargs):
        super(RegisterForm, self).__init__(*args, **kwargs)
        #Override the default method
        self.favor.choices = ((1,'Basketball'), (2,'Football'), (3,'Badminton'))

    #Hook function
    def validate_pwd_confirm(self, field):
        """
        Custom pwd_confirm field rules, for example: whether it is consistent with the pwd field
        :param field:
        :return:
        """
        # At the beginning of initialization, there are already all values ​​in self.data

        if field.data != self.data['pwd']:
            # raise validators.ValidationError("Password is inconsistent") # Continue subsequent verification
            raise validators.StopValidation("Password is inconsistent") # Do not continue subsequent verification


@app.route('/register', methods=['GET','POST'])
def register():
    if request.method =='GET':
        #data={'gender': 1} Pass to the default value displayed on the front-end page, here only gender is set, and other fields can also be set in this way
        form = RegisterForm(data={'gender': 1})
        return render_template('register.html', form=form)
    else:
        form = RegisterForm(formdata=request.form)
        if form.validate():
            print('The data submitted by the user passes the format verification, and the submitted value is:', form.data)
        else:
            print(form.errors)
        return render_template('register.html', form=form)



if __name__ =='__main__':
    app.run()

(2).register.html

You can directly loop out all fields

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


<h1>User registration</h1>
<form method="post" novalidate style="padding:0 50px">
    {% for item in form %}
    <p>{{item.label}}: {{item}} {{item.errors[0] }}</p>
    {% endfor %}
    <input type="submit" value="Submit">

    
</form>
</body>
</html>

The registration page shows:

Reference: https://cloud.tencent.com/developer/article/1139359 Flask signal and wtforms one, signal two, wtforms component usage-cloud + community-Tencent Cloud