Flask信号和wtforms 一、信号二、wtforms组件使用

一、信号

1.1.所有内置信号

request_started = _signals.signal('request-started')                # 请求到来前执行
request_finished = _signals.signal('request-finished')              # 请求结束后执行
 
before_render_template = _signals.signal('before-render-template')  # 模板渲染前执行
template_rendered = _signals.signal('template-rendered')            # 模板渲染后执行
 
got_request_exception = _signals.signal('got-request-exception')    # 请求执行出现异常时执行
 
request_tearing_down = _signals.signal('request-tearing-down')      # 请求执行完毕后自动执行(无论成功与否)
appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 请求上下文执行完毕后自动执行(无论成功与否)
 
appcontext_pushed = _signals.signal('appcontext-pushed')            # 请求上下文push时执行
appcontext_popped = _signals.signal('appcontext-popped')            # 请求上下文pop时执行
message_flashed = _signals.signal('message-flashed')                # 调用flask在其中添加数据时,自动触发

1.2.信号简单实例

Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为。首先要安装blinker

pip install blinker
from flask import Flask,signals

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

def func(*args,**kwargs):
    print('触发信号',args,kwargs)
signals.request_started.connect(func)

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

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

运行结果:

二、wtforms组件使用

2.1.安装

WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。安装方法

pip install wtforms

2.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 lang="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>

用户名和密码格式不对

2.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>

注册页面显示:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏QQ音乐前端团队专栏

web模拟终端博客系统

前段时间做了一个非常有意思的模拟终端的展示页.这个页面非常有意思,它可以作为个人博客系统或者给 Linux 初学者学习终端命令,现分享给大家~

1.1K70
来自专栏黒之染开发日记

webstorm/phpstorm 配置白鹭引擎快捷键编译TypeScript

3、 选择与截图中一致,或者选你看得懂的选项,这里是说要侦听的ts文件位于哪里,图片中的选项表示整个项目中的ts文件

29530
来自专栏魏艾斯博客www.vpsss.net

wordpress 无法建立到 wordpress org 安全连接的解决办法

网友求助,说安装 Avada 插件时遇到如下错误提示:wordpress 无法建立到 wordpress.org 的安全连接,请联系您的服务器管理员。询问网友得...

19930
来自专栏魏艾斯博客www.vpsss.net

wordpress 无法建立到 wordpress org 安全连接的解决办法

网友求助,说安装 Avada 插件时遇到如下错误提示:wordpress 无法建立到 wordpress.org 的安全连接,请联系您的服务器管理员。询问网友得...

16820
来自专栏中国Android研究院

Flutter开发环境搭建

对于上文Android Studio✗部分,只需要在AndroidStudio中的Plugin中安装Flutter插件即可。 对于'Some android l...

13130
来自专栏计算机编程

ionic4 -- angular 跳转页面

ionic4 与前辈们最大的不同就是通过angular引入了route,这样每次跳转的时候只需要直接跳转对应的路由地址就可以了,给了路由器上的解耦,也解决了原来...

1.2K20
来自专栏Nian糕的私人厨房

CSS 预处理语言 Less

Less 是一门 CSS 预处理语言,作为 CSS 的一种扩展,Less 不仅完全兼容 CSS 语法,而且连新增的特性也是使用 CSS 语法,增加了诸如变量、混...

15620
来自专栏Java后端生活

Linux(六)vi和vim编辑器的使用

33550
来自专栏杨龙飞前端

渐进增强 VS 优雅降级

31540
来自专栏闻道于事

IntelliJ IDEA 2018.3 重大升级(转)

2018.11.28 IntelliJ IDEA 2018.3 正式版发布。对于一个忠实爱好者,迫不及待的我下载了最新版本来体验下。而且 IDEA 今年的第三次...

34220

扫码关注云+社区

领取腾讯云代金券