1.7 flask 的组件 wtfroms使用

2019-1-7 17:59:37

还有两天左右flask就结束啦!昨晚逛了一下吾爱破解还有慕课,发现有三个意外项目,

Django生鲜项目,flask电影网站项目,vue美团网项目,都保存百度云啦,寒假可以搞事情啦

还有十天左右的视频,看完后认证整理博客,然后争取整理本书,到时候回学校打印,233333333!

想想都是很有成就感的一件事情!

越努力,越幸运!永远不要高估自己!

 

今天讲了wtfroms 组件,就是Django中的form  modelsForm 类似!

书上介绍的组件很多,flask那本书!

flask参考链接: https://www.cnblogs.com/wupeiqi/articles/8202357.html

 

 

还讲了 重要的东西  localproxy

这是关于localproxy的一个demo

s1.py

# by luffycity.com

DATA = {
    'request':{
        'method':"GET",
        'form':{}
    },
    'session':{
        'user':'alex',
        'age':"19"
    }
}

class LocalProxy(object):
    def __init__(self,key):
        self.key = key
    def get_dict(self):
        return DATA[self.key]

    def __str__(self):
        return 'asdf'

    def __getattr__(self, item):
        data_dict = self.get_dict()
        return data_dict[item]

    def __getitem__(self, item):
        data_dict = self.get_dict()
        return data_dict[item]

    def __add__(self, other):
        return other + 1

request = LocalProxy('request')
session = LocalProxy('session')

s2.py

from s2 import request,session



print(request.method)
print(request.form)

print(session.user)
print(session.age)

这是在flask中实现上下文管理  resquest 和session 的方法

from flask import Flask,request,session

app = Flask(__name__)


@app.route('/index')
def index():
    # 1. request是LocalProxy对象
    # 2. 对象中有method、执行__getattr__
    print(request.method)
    # request['method']
    # request + 1

    # 1. session是LocalProxy对象
    # 2. LocalProxy对象的__setitem__
    session['x'] = 123

    return "Index"


if __name__ == '__main__':
    app.run()
    # app.__call__
    # app.wsgi_app

"""
第一阶段:请求到来
    将request和Session相关数据封装到ctx=RequestContext对象中。
    再通过LocalStack将ctx添加到Local中。
    __storage__ = {
        1231:{'stack':[ctx(request,session)]}
    }
第二阶段:视图函数中获取request或session
    方式一:直接找LocalStack获取
            from flask.globals import _request_ctx_stack
            print(_request_ctx_stack.top.request.method)
            
    方式二:通过代理LocalProxy(小东北)获取
            from flask import Flask,request
            print(request.method)
            
"""

这是很重要的一张图,搞懂这个图就清楚 reqeust session  g 和app 的上下文管理用法啦

 

 

wtforms基本使用

贴上源码

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__)


class LoginForm(Form):
    name = simple.StringField(
        validators=[
            validators.DataRequired(message='用户名不能为空.'),
            # validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d')
        ],
        widget=widgets.TextInput(),
        render_kw={'placeholder':'请输入用户名'}
    )
    pwd = simple.PasswordField(
        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个特殊字符')

        ],
        render_kw={'placeholder':'请输入密码'}
    )


@app.route('/login',methods=['GET','POST'])
def login():
    if request.method == "GET":
        form = LoginForm()
        # print(form.name,type(form.name)) # form.name是StringField()对象, StringField().__str__
        # print(form.pwd,type(form.pwd))   # form.pwd是PasswordField()对象,PasswordField().__str__
        return render_template('login.html',form=form)

    form = LoginForm(formdata=request.form)
    if form.validate():
        print(form.data)
        return redirect('https://www.luffycity.com/home')
    else:
        # print(form.errors)
        return render_template('login.html', form=form)


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

    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 # int("1")
    )
    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, ]
    )



@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        form = RegisterForm()
        return render_template('register.html', form=form)

    form = RegisterForm(formdata=request.form)
    if form.validate():
        print(form.data)
        return redirect('https://www.luffycity.com/home')

    return render_template('register.html', form=form)

import helper
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=helper.fetch_all('select id,name from tb1',[],type=None)


@app.route('/user')
def user():
    if request.method == "GET":
        #form = UserForm(data={'name':'alex','city':3})
        form = UserForm()
        return render_template('user.html',form=form)


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

连接数据库用的连接池

helper.py

import pymysql
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='123456',
        database='s9day119',
        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

login.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" 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>

register.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" novalidate>

        {% for field in form %}
        <p>{{field.label}}: {{field}}   {{field.errors[0]}}</p>
        {% endfor %}

        <input type="submit" value="提交">
    </form>
</body>
</html>

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>

贴上笔记:

s9day119 

内容回顾:
    第一部分:Flask
        1. 谈谈你对django和flask的认识?
        
        2. Flask基础:
            - 配置文件:反射+importlib
            - 路由系统:
                - 装饰器 @app.route()
                - 参数:
                    - url
                    - endpoint
                    - methods
                - 加装饰器
                    - endpoint默认是函数名
                    - functools.wraps(func)  + functools.partial
                - 写路由两种方式:
                    - 装饰器
                    - add_url_rule
                - 自定义支持正则的URL
            - session 
            - 蓝图 
                - 目录结构划分
                - 前缀
                - 特殊装饰器
        3. 上下文管理 
            - threading.local
                - 为每个线程开辟空间,使得线程之间进行数据隔离。
                - 应用:DBUtils中为每个线程创建一个数据库连接时使用。
            - 面向对象特殊方法:
                - getattr
                - setattr
                - delattr
            - 偏函数
            - 单例模式
            - 请求上下文流程:
                - 班级示例:
                - 源码流程:
                    - __call__
                    - wsgi_app
                        - ctx = RequestContext(): 封装= 请求数据+空session
                        - ctx.push() : 将ctx传给LocalStack对象,LocalStack再将数据传给Local存储起来。
                                       问题:Local中是如何存储?
                                            __storage__ = {
                                                1231:{}
                                            }
                                        问题:LocalStack作用?
                                            __storage__ = {
                                                1231:{stack:[ctx] }
                                            }
                    - 视图函数:再次去获取
                - 关闭
        
        
        4. 第三方组件:
            1. flask-session 
            2. DBUtils 
    
    第二部分:数据库&前端
        1. 什么是响应式布局?
            @media属性
        2. MySQL数据库
            - 引擎:
                - innodb
                    - 支持事务
                    -- 行锁
                        - 表锁
                        - 示例:
                            - 终端:
                                begin;
                                select xx from xx for update;
                                commit;
                            - pymysql
                                cursor.execute('select * from xx for update')
                            - django
                                with trancation.automic():
                                    models.User.objects.all().for_update()
                - mysaim
                    - 不支持事务
                    -- 表锁 
                    - 快
                        
今日内容:
    1. 上下文管理:LocalProxy对象
    2. 上下文管理:
            - 请求上下文:request/session
            - App上下文: app/g
    3. 第三方组件:wtforms
        作用:
            - 生成HTML标签
            - form表单验证
        安装:
            pip3 install wtforms 
            
        使用:
            - 用户登录
            - 用户注册
            - 从数据库获取数据

内容详细:
    1. 上下文管理:LocalProxy对象
    2. 上下文管理:
            - 请求上下文(ctx=RequestContext()):request/session
            -  App上下文(app_ctx=AppContext()): app/g
            
        - 程序启动:
            两个Local:
                local1 = {
                
                }
                
                local2 = {
                
                }
        
            两个LocalStack:
                _request_ctx_stack
                _app_ctx_stack
        - 请求到来
            对数据进行封装:
                ctx = RequestContext(request,session)
                app_ctx = AppContext(app,g)
            保存数据:
                将包含了(app,g)数据的app_ctx对象,利用 _app_ctx_stack(贝贝,LocalStack())将app_ctx添加到Local中
                    storage = {
                        1231:{stack:[app_ctx(app,g),]}
                    }
                将包含了request,session数据的ctx对象,利用_request_ctx_stack(刘淞,LocalStack()),将ctx添加到Local中
                    storage = {
                        1231:{stack:[ctx(request,session),]}
                    }
                    
        - 视图函数处理:
            
            
            from flask import Flask,request,session,current_app,g

            app = Flask(__name__)


            @app.route('/index')
            def index():
                # 去请求上下文中获取值 _request_ctx_stack
                request.method # 找小东北获取值
                session['xxx'] # 找龙泰获取值
                
                # 去app上下文中获取值:_app_ctx_stack 
                print(current_app)
                print(g)
                
                return "Index"


            if __name__ == '__main__':
                app.run()
                app.wsgi_app
        
        - 结束
            _app_ctx_stack.pop()
            _request_ctx_stack.pop()

            
            
        问题:
            1. Flask中g的生命周期?
            2. g和session一样吗?
            3. g和全局变量一样吗?
                

 

转载于:https://www.cnblogs.com/zhen1996/p/10234792.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值