• WTForms


    WTForms是一个支持多个web框架的form组件,主要用于生成HTML标签,对用户请求数据进行验证。

    安装

    pip install wtforms
    

    使用

    用户注册示例

    from flask import Flask
    from flask import request
    from flask import render_template
    from wtforms import Form
    from wtforms.fields import simple
    from wtforms.fields import core
    from wtforms import validators
    
    app = Flask(__name__)
    
    
    class RegisterForm(Form):
        user = simple.StringField(
            label='用户名',
            validators=[
                validators.DataRequired(message='用户名不能为空'),
                validators.Length(min=6, max=16, message='用户名的长度为6-16'),
            ],
        )
        pwd = simple.PasswordField(
            label='密码',
            validators=[
                validators.DataRequired(message='密码不能为空'),
                validators.Regexp(
                    regex=r'(?=.*d)(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,16}',
                    message='密码中必须包含字母、数字、特殊字符,至少8个字符,最多16个字符',
                )
            ],
        )
        pwd_confirm = simple.PasswordField(
            label='确认密码',
            validators=[
                validators.DataRequired(message='密码不能为空'),
                validators.EqualTo('pwd', message='两次密码输入不一致')
            ],
        )
        email = simple.StringField(
            label='邮箱',
            validators=[
                validators.DataRequired(message='邮箱不能为空'),
                validators.Email('邮箱格式错误'),
            ]
        )
        gender = core.RadioField(
            label='性别',
            choices=[(1,'男'),(2,'女')],
            validators = [validators.DataRequired(message='性别不能为空')],
            coerce=int                  # 将提交的字符串类型的数据,转换成int类型
        )
    
        city = core.SelectField(
            label='城市',
            choices=[
                ('bj','北京'),
                ('wh','武汉'),
                ('sh','上海'),
            ],
            validators=[validators.DataRequired(message='城市不能为空')],
        )
        hobby = core.SelectMultipleField(
            label='爱好',
            choices=[
                (1, '写代码'),
                (2, '睡觉'),
                (3, '吃饭'),
            ],
            validators=[validators.DataRequired(message='爱好不能为空')],
            coerce=int,
            default=[1, 2]
        )
    
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            for name, field in self._fields.items():
                if name == 'gender':
                    continue
                field.render_kw = {"class":"form-control"}
    
    
    @app.route('/register', methods=['GET', 'POST'])
    def register():
        if request.method == "GET":
            form = RegisterForm(data={'city': 'bj'})
            return render_template('register.html', form=form)
    
        if request.method == 'POST':
            form = RegisterForm(formdata=request.form)
            if form.validate():
                print(form.data)
                return '验证成功'
            else:
                return render_template('register.html', form=form)
    
    
    if __name__ == '__main__':
        app.run()
    
    
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <style>
            ul{
                margin: 0;
                padding: 0;
                list-style-type: none;
            }
        </style>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <form class="form-horizontal col-md-8 col-md-offset-2" action="" method="post" novalidate>
                {% for item in form %}
                <div class="form-group">
                    <label for="{{ item.id }}" class="col-sm-2 control-label">{{item.label}}:</label>
                    <div class="col-sm-10">
                        {{ item }}
                        <span style="color: red">{{item.errors.0}}</span>
                    </div>
                </div>
                {% endfor%}
                <div class="text-center">
                    <input type="submit" value="提交" class="btn btn-success">
                </div>
            </form>
        </div>
    </div>
    </body>
    </html>
    

    CSRF_token

    from wtforms.csrf.core import CSRF
    from hashlib import md5
    
    
    class MyCSRF(CSRF):
        def setup_form(self, form):
            self.csrf_context = form.meta.csrf_context()
            self.csrf_secret = form.meta.csrf_secret
            return super().setup_form(form)
    
        def generate_csrf_token(self, csrf_token):
            gid = self.csrf_secret + self.csrf_context
            token = md5(gid.encode('utf-8')).hexdigest()
            return token
    
        def validate_csrf_token(self, form, field):
            print(field.data, field.current_token)
            if field.data != field.current_token:
                raise ValueError('Invalid CSRF')
    
    
    class LoginForm(Form):
        user = simple.StringField(
            render_kw={
                'class': 'xxx',
                'placeholder': '请输入用户名'
            },
            validators=[
                validators.DataRequired(message='用户名不能为空'),
                validators.Length(min=6, max=16, message='用户名长度在5-16位')
            ]
        )
    
        pwd = simple.PasswordField(
            render_kw={
                'class': 'xxx',
                'placeholder': '请输入密码'
            },
            validators=[
                validators.DataRequired(message='密码不能为空'),
                validators.Regexp(
                    regex=r'(?=.*d)(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,16}',
                    message='密码中必须包含字母、数字、特殊字符,至少8个字符,最多16个字符',
                )
            ]
        )
    
        class Meta:
            csrf = True
            csrf_field_name = 'csrf_token'
            csrf_secret = 'xxxxxx'
            csrf_context = lambda x: request.url
            csrf_class = MyCSRF
    

    模板文件中,在form标签内添加一行

    {{ form.csrf_token }}
    

    钩子函数

    validate_字段名

    def validate_user(self, field):
        print(field.data)
        if field.data != 'xxxxxx':
            # raise validators.ValidationError('用户名不是xxxxxx')
    
            # 当前字段不再进行后续规则验证
            raise validators.StopValidation('用户名不是xxxxxx')
    
  • 相关阅读:
    [SharePoint 2010] 自定义字段类型开发(二)
    [SharePoint 2007/2010]Query SharePoint Calendar Event
    打印出带颜色的调试信息
    c语言调试开关
    c语言调试接口
    字符串截取
    黑客
    【原创】洛谷 LUOGU P3379 【模板】最近公共祖先(LCA) -> 倍增
    【转载】从头到尾彻底理解KMP
    【原创】tarjan算法初步(强连通子图缩点)
  • 原文地址:https://www.cnblogs.com/xiasir/p/13044925.html
Copyright © 2020-2023  润新知