天天看點

Flask-wtforms

wtforms元件使用

1.1.安裝

WTForms是一個支援多個web架構的form元件,主要用于對使用者請求資料進行驗證。安裝方法

pip install wtforms      

1.2.使用者登入

 使用者登入時,對使用者名和密碼進行驗證

(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='使用者名',
        #自定義的驗證規則
        validators=[
            validators.DataRequired(message='使用者名不能為空.'),
            validators.Length(min=6, max=18, message='使用者名長度必須大于%(min)d且小于%(max)d')
        ],
        #頁面顯示的插件
        widget=widgets.TextInput(),
        #加屬性
        render_kw={'class': 'form-control'}
    )

    pwd = simple.PasswordField(
        label='密碼',
        validators=[
            validators.DataRequired(message='密碼不能為空.'),
            validators.Length(min=8, message='使用者名長度必須大于%(min)d'),
            #正規表達式
            validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,}",
                              message='密碼至少8個字元,至少1個大寫字母,1個小寫字母,1個數字和1個特殊字元')

        ],
        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('使用者送出資料通過格式驗證,送出的值為:', form.data)
        else:
            print(form.errors)
        return render_template('login.html', form=form)

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

(2)login.html

<!DOCTYPE html>
<html en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登入</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="送出">
    
</form>
</body>
</html>      

使用者名和密碼格式不對

Flask-wtforms

1.3.使用者注冊

(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='使用者名',
        validators=[
            validators.DataRequired()
        ],
        widget=widgets.TextInput(),
        render_kw={'class': 'form-control'},
        default='derek'
    )

    pwd = simple.PasswordField(
        label='密碼',
        validators=[
            validators.DataRequired(message='密碼不能為空.')
        ],
        widget=widgets.PasswordInput(),
        render_kw={'class': 'form-control'}
    )

    pwd_confirm = simple.PasswordField(
        label='重複密碼',
        validators=[
            validators.DataRequired(message='重複密碼不能為空.'),
            #EqualTo:要跟那個字段一樣
            validators.EqualTo('pwd', message="兩次密碼輸入不一緻")
        ],
        widget=widgets.PasswordInput(),
        render_kw={'class': 'form-control'}
    )

    email = html5.EmailField(
        label='郵箱',
        validators=[
            validators.DataRequired(message='郵箱不能為空.'),
            validators.Email(message='郵箱格式錯誤')
        ],
        widget=widgets.TextInput(input_type='email'),
        render_kw={'class': 'form-control'}
    )

    #RadiField單選
    gender = core.RadioField(
        label='性别',
        choices=(
            (1, '男'),
            (2, '女'),
        ),
        coerce=int      #因為前段送出過來的資料都是str格式,比如“1”,“2”,這裡轉換成int
    )
    #單選的下拉框
    city = core.SelectField(
        label='城市',
        choices=(
            ('bj', '北京'),
            ('sh', '上海'),
        )
    )
    #多選的下拉框
    hobby = core.SelectMultipleField(
        label='愛好',
        choices=(
            (1, '籃球'),
            (2, '足球'),
        ),
        coerce=int
    )

    favor = core.SelectMultipleField(
        label='喜好',
        choices=(
            (1, '籃球'),
            (2, '足球'),
        ),
        widget=widgets.ListWidget(prefix_label=False),
        option_widget=widgets.CheckboxInput(),   #多選
        coerce=int,
        default=[1, 2]
    )

    def __init__(self, *args, **kwargs):
        super(RegisterForm, self).__init__(*args, **kwargs)
        #重寫預設的方法
        self.favor.choices = ((1, '籃球'), (2, '足球'), (3, '羽毛球'))

    #鈎子函數
    def validate_pwd_confirm(self, field):
        """
        自定義pwd_confirm字段規則,例:與pwd字段是否一緻
        :param field:
        :return:
        """
        # 最開始初始化時,self.data中已經有所有的值

        if field.data != self.data['pwd']:
            # raise validators.ValidationError("密碼不一緻") # 繼續後續驗證
            raise validators.StopValidation("密碼不一緻")  # 不再繼續後續驗證


@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        #data={'gender': 1 }  傳到前端頁面顯示的預設值,這裡隻設定了gender,其它字段也可以通過這種方式設定
        form = RegisterForm(data={'gender': 1})
        return render_template('register.html', form=form)
    else:
        form = RegisterForm(formdata=request.form)
        if form.validate():
            print('使用者送出資料通過格式驗證,送出的值為:', form.data)
        else:
            print(form.errors)
        return render_template('register.html', form=form)



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

(2).register.html

可以直接循環取出所有字段

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


<h1>使用者注冊</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="送出">

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

注冊頁面顯示:

Flask-wtforms