• 十三 .Flask wtforms组件使用 和选择框动态数据实时更新


    一 . wtforms组件使用     选择框动态数据实时更新

    https://www.cnblogs.com/lovershowtime/p/11384494.html

    https://www.cnblogs.com/wupeiqi/p/8202357.html  

    1.wtforms组件使用(登录)

    1. 用户登录
    当用户登录时候,需要对用户提交的用户名和密码进行多种格式校验。如:
    用户不能为空;用户长度必须大于6;
    密码不能为空;密码长度必须大于12;密码必须包含 字母、数字、特殊字符等(自定义正则);
    login.html

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>登录</h1> <form method="post"> <!--<input type="text" name="name">--> <p>{{form.name.label}} {{form.name}} {{form.name.errors[0] }}</p> <!--<input type="password" name="pwd">--> <p>{{form.pwd.label}} {{form.pwd}} {{form.pwd.errors[0] }}</p> <input type="submit" value="提交"> </form> </body> </html>
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    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-zd$@$!%*?&]{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.wtforms组件使用(注册)

    注册页面需要让用户输入:用户名、密码、密码重复、性别、爱好等
    reg.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>
    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='哈哈哈哈哈'
        )
    
        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='重复密码不能为空.'),
                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'}
        )
    
        gender = core.RadioField(
            label='性别',
            choices=(
                (1, ''),
                (2, ''),
            ),
            coerce=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('/reg/', methods=['GET', 'POST'])
    def register():
        if request.method == 'GET':
            form = RegisterForm(data={'gender': 1})
            return render_template('reg.html', form=form)
        else:
            form = RegisterForm(formdata=request.form)
            if form.validate():
                print('用户提交数据通过格式验证,提交的值为:', form.data)
            else:
                print(form.errors)
            return render_template('reg.html', form=form)
    
    
    if __name__ == '__main__':
        app.run()

    3.wtforms组件使用(选择框动态数据实时更新)

    静态字段
    import  cc
    
    class Foo(object):
    
        country =cc.fetch_all('select id,name from student',[],type=None)
        def __init__(self):
            self.name = '哈哈哈'
    
    print(Foo.country)
    obj = Foo()    #程序运行起来静态只会取一次数据   后面管你实例化多少次都没有用都不会取值   只是最开始取了一次
    obj = Foo()
    obj = Foo()
    obj = Foo()
    obj = Foo()
    obj = Foo()
    
    
    # ((1, '南昌'), (2, '上海'), (3, '成都'), (4, '爱好'))
    user.html

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <form method="post"> {% for field in form %} <p>{{field.label}}: {{field}} {{field.errors[0]}}</p> {% endfor %} <input type="submit" value="提交"> </form> </body> </html>
    from flask import Flask,request,render_template,session,current_app,g,redirect
    from wtforms import Form
    from wtforms.fields import simple
    from wtforms.fields import html5
    from wtforms.fields import core
    
    from wtforms import widgets
    from wtforms import validators
    app = Flask(__name__)
    
    import cc
    class UserForm(Form):
        city = core.SelectField(
            label='城市',
            choices=(),
            coerce=int  #  内部把提交的字符串转换成数字  在匹配
        )
        name = simple.StringField(label='姓名')
        def __init__(self,*args,**kwargs):      # 每次实例化都会从数据库取一次   做带数据库和展示页面数据实时更新
            super(UserForm,self).__init__(*args,**kwargs)
            self.city.choices=cc.fetch_all('select id,name from student',[],type=None)  # type=None  表示获取到的数据为元祖
    
    
    @app.route('/user/')
    def user():
        if request.method == "GET":
            form = UserForm(data={'name':'李四','city':1})    #设置默认值  编辑 显示默认值
            # form = UserForm()
            return render_template('user.html',form=form)
    
    if __name__ == '__main__':
        app.run()
    
    # mysql> create table student( id int primary key auto_increment,name varchar(20) not null);
    数据库连接池
    
    
    from DBUtils.PooledDB import PooledDB, SharedDBConnection
    import pymysql
    
    POOL = PooledDB(
            creator=pymysql,  # 使用链接数据库的模块
            maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
            mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
            maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
            maxshared=3,
            # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
            blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
            maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
            setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
            ping=0,
            # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
            host='127.0.0.1',
            port=3306,
            user='root',
            password='root',
            database='dba1',
            charset='utf8'
        )
    
    def connect(type):
        conn = POOL.connection()
        cursor = conn.cursor(cursor=type)
        return conn,cursor
    
    
    def connect_close(conn,cursor):
        cursor.close()
        conn.close()
    
    def fetch_all(sql,args,type=pymysql.cursors.DictCursor):
        conn,cursor = connect(type)
    
        cursor.execute(sql, args)
        record_list = cursor.fetchall()
        connect_close(conn,cursor)
    
        return record_list
    
    
    def fetch_one(sql, args):
        conn, cursor = connect()
        cursor.execute(sql, args)
        result = cursor.fetchone()
        connect_close(conn, cursor)
    
        return result
    
    
    def insert(sql, args):
        conn, cursor = connect()
        row = cursor.execute(sql, args)
        conn.commit()
        connect_close(conn, cursor)
        return row
       
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
        <form method="post" novalidate>
            <p>用户名:{{form.name}}  {{form.name.errors[0]}}</p>
            <p>密码:{{form.pwd}}  {{form.pwd.errors[0]}} </p>
            <p><input type="submit" value="提交"  ></p>
        </form>
    </body>
    </html>
    from flask import Flask,request,render_template,session,current_app,g,redirect
    from wtforms import Form
    from wtforms.csrf.core import CSRF
    from wtforms.fields import simple
    from wtforms.fields import html5
    from wtforms.fields import core
    from hashlib import md5
    from wtforms import widgets
    from wtforms import validators
    app = Flask(__name__)
    class LoginForm(Form):
        name = simple.StringField(
            validators=[
                validators.DataRequired(message='用户名不能为空.'),
            ],
            widget=widgets.TextInput(),
            render_kw={'placeholder':'请输入用户名'}
        )
        pwd = simple.PasswordField(
            validators=[
                validators.DataRequired(message='密码不能为空.'),
    
            ],
            render_kw={'placeholder':'请输入密码'}
        )
    
        def validate_name(self, field):    钩子函数
            """
            自定义name字段规则
            :param field:
            :return:
            """
            # 最开始初始化时,self.data中已经有所有的值
            print('钩子函数获取的值',field.data)
            if not field.data.startswith('old'):
                raise validators.ValidationError("用户名必须以old开头") # 继续后续验证
                # raise validators.StopValidation("用户名必须以old开头")  # 不再继续后续验证
    
    @app.route('/login/',methods=['GET','POST'])
    def login():
        if request.method == "GET":
            form = LoginForm()
            return render_template('login.html',form=form)
    
        form = LoginForm(formdata=request.form)
        if form.validate():
            print(form.data)
            return redirect('https://home.cnblogs.com/u/lovershowtime/')
        else:
            return render_template('login.html', form=form)
    
    
    if __name__ == '__main__':
        app.run()

     

  • 相关阅读:
    实战:推断mysql中当前用户的连接数-分组筛选
    Codeforces Round #250 (Div. 2) A
    设计模式(3)-对象创建型模式-Abstract Factory模式
    设计模式
    uva 11825 Hackers&#39; Crackdown (状压dp,子集枚举)
    java中不常见的keyword:strictfp,transient
    C++中数组初始化
    Hadoop 开源调度系统zeus(二)
    Python发一个GET请求
    【代码优化】equals深入理解
  • 原文地址:https://www.cnblogs.com/lovershowtime/p/11751335.html
Copyright © 2020-2023  润新知