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':""
    }
}
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='',
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和全局变量一样吗?
1.7 flask 的组件 wtfroms使用的更多相关文章
- flask wtforms组件详解
		
一.简介 在flask内部并没有提供全面的表单验证,所以当我们不借助第三方插件来处理时候代码会显得混乱,而官方推荐的一个表单验证插件就是wtforms.wtfroms是一个支持多种web框架的form ...
 - Flask 三方组件 WTForms
		
WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证 from flask import Blueprint from flask import request fro ...
 - flask seesion组件
		
一.简介 flask中session组件可分为内置的session组件还有第三方flask-session组件,内置的session组件功能单一,而第三方的flask-sessoin可支持re ...
 - Flask wtform组件
		
Wtforms简介 WTForms是一个支持多个web框架的form组件 主要能够帮助我们生成html标签 对数据进行验证 安装 pip install wtforms Wtforms的使用 这里借助 ...
 - 4.flask第三方组件
		
1.flask-session的使用 在flask中,有一个app.session_interface = SecureCookieSessionInterface(),也就是存session,调用o ...
 - Flask 三方组件 Flask-Session
		
使用 from flask import session, Flask from flask_session import Session from redis import Redis app = ...
 - Flask第三方组件之flask_session
		
flask默认提供了session, 但是存在以下问题: ① session数据存在客户端, 不安全 ② 大小有限制 ③ 增加了客户端的压力 所以才产生了很多第三方的session机制, 我使用的是f ...
 - Flask第三方组件 之 Flask-Session
		
原生session:交由客户端保管机制,安全性相对较差,优势是一点都不占用服务器空间 Flask-Session: 解决原生session的劣势 安装包 from flask import Flask ...
 - Flask 基础组件(十):中间件
		
from flask import Flask, flash, redirect, render_template, request app = Flask(__name__) app.secret_ ...
 
随机推荐
- Network Monitoring in Software-Defined Networking :A Review(综述)
			
来源:IEEE SYSTEMS JOURNAL 发表时间:2018 类型:综述 主要内容:概述了SDN监控的发展,并从收集信息.预处理.传送信息.分析.和描述五个阶段进行解读,并比较了传统网络和SDN ...
 - python之文件处理
			
第一:文件基本处理流程 f=open('text') one_line=f.readline() print('one_line:',one_line) #读取一行 print('分割线'.cente ...
 - hdu3466 Proud Merchants(01背包)
			
https://vjudge.net/problem/HDU-3466 一开始想到了是个排序后的背包,但是排序的策略一直没对. 两个物品1和2,当p1+q2>p2+q1 => q1-p1& ...
 - 搜狗拼音输入法 V9.1.0.2589 最新去广告精简优化版
			
搜狗拼音输入法9.0 正式版例行发布,最新版字母代号b,详细版本号为v9.1.0.2589:搜狗拼音输入法是电脑装机必备软件,版本有传统版和智慧版之分,其打字超准.词库超大.速度飞快.外观漂亮,因此使 ...
 - APP中的图片如何长按可以下载并保存图片到相册
			
直接上图 方式一: 实现方式二: 方式三:
 - CoordinatorLayout使用详解: 打造折叠悬浮效果
			
1.简介 CoordinatorLayout遵循Material 风格,包含在 support Library中,结合AppbarLayout, CollapsingToolbarLayout等 可 ...
 - Docker 管理工具 Portainer部署
			
Docker 管理工具 Portainer部署 一.官网 官网:http://www.portainer.io 演示地址:http://demo.portainer.io 用户名:admin 密码:t ...
 - [oracle] Oracle存储过程里操作BLOB的字节数据的办法,例如写入32位整数
			
作者: zyl910 一.缘由 BLOB是指二进制大对象,也就是英文Binary Large Object的缩写. 在很多时候,我们是通过其他编程语言(如Java)访问BLOB的字节数据,进行字节级的 ...
 - [Java] 绕过证书验证调 HTTPS 接口时报 “SSLHandshakeException: DHPublicKey does not comply to algorithm constraints”的解决办法
			
作者: zyl910 一.缘由 最近有在对接一个无证书的HTTPS接口时,总是收到"SSLHandshakeException: DHPublicKey does not comply to ...
 - 【20180409】IT管理之IT十二条令
			
团队越来越大,靠人管几乎有力无心,只能靠制度管理了. 前段时间对部门颁布了12条令,效果明显. 特此Mark. 汇报: 三条总结:汇报讲究精简,一个事情最多一句话概括. 一页报告:内容精简,报告一页w ...