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_ ...
随机推荐
- Windows软件
安装地址:C:\Users\Username\AppData\Local\Programs 网页 Chrome 下载地址:https://www.google.cn/chrome/thank-you. ...
- Nancy的基本用法
在前面的文章轻量级的Web框架——Nancy中简单的介绍了一下Nancy的特点,今天这里就介绍下它的基本用法,由于2.0的版本还是预览状态,我这里用的是1.4版本,和最小的版本API还是有些差异的. ...
- .Net转Java.05.为啥MySQL没有nolock
今天忽然想到一个问题,原来为了提高SQL Server性能,公司规定查询语句一般都要加 WITH (NOLOCK)的 现在转Java了,用了MySQL为啥不提这个事情了? 先在MySQL里写了一个查询 ...
- 分享一个整理Mac储存空间的软件,有效清理xcode的垃圾
苹果的电脑还是比windows的要好,我这台用了3年时间,作为编程工作天天用,现在愣是一点儿也没有卡顿,如果换作是windows的电脑,我敢保证肯定是卡成狗,相信做编程的你肯定少补了一台mac. ma ...
- android:第十章,后台的默默劳动者——服务,学习笔记
一.多线程 1)本章首先介绍了安卓的多线程编程,说明在子线程中如果要修改UI,必须通过Handler, Message, MessageQueue, Looper来实现,但是这样毕竟太麻烦了. 2) ...
- spring @Transactional 事务注解
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = ...
- 小程序longpress的bug及其解决
我的小程序中,用到一个长按修改的功能,设计是这样的,短按tap,长按longpress 但是,偶尔出现长按无效的情况.我自己都经常碰到,今天仔细研究,用半天时间反复寻找,重现,发现问题和内存或别的因素 ...
- 微信小程序官方DEMO解读
我们在开始微信小程序开发的时候,对JS,HTML等前端知识一无所知,完完全全就是门外汉在尝试一个新的方向. 在下载好开发工具,微信就已经提供了一个DEMO例子: 从程序开发的角度来看这个陌生的目录结构 ...
- celery --分布式任务队列
一.介绍 celery是一个基于python开发的分布式异步消息任务队列,用于处理大量消息,同时为操作提供维护此类系统所需的工具. 它是一个任务队列,专注于实时处理,同时还支持任务调度.如果你的业务场 ...
- WCF-Oracel适配器针对UDT的使用配置与注意事项
配置方法 1.针对Oracle UDT 的数据类型需要在开发过程中手动配置生成的DLL位置和Key位置,Visual Studio->添加生成项目->Add Adapter Metadat ...