flask 之 wtforms

 复习链接整理

先把标题给列出来,我们的flask到了这个阶段就需要把我们的源码都吃透了,源码都需要去整理出来

 

在看wtform源码之前我们先把面向对象的一些知识点给补充一下

 

1 class A():
2     ...
3 class B(A):
4     ...
5 class C():
6     ...
7 class D(B,C):
8     ...
9 print(D.__mro__)  # 深度优先
mro
 1 class HeType(type):
 2     def __init__(self, *args, **kwargs):
 3         super(HeType, self).__init__(*args, **kwargs)
 4         print('hello')
 5 
 6 
 7 class Fo(object, metaclass=HeType):
 8     """
 9     Fo这个类是通过metaclass来选择我们自定义的HeType来创建的,而我们自定义的类又继承了Type类,
10 
11     """
12     ...
13 
14 
15 obj = Fo()
16 """
17 0,先执行我们的HeType里面的__init__
18 1,然后是HeType的__call__
19 2,再来就是Fo的__new__
20 3,最后是Fo的__init__
21 """
metaclass
 1 class Fo():
 2     name='peter'
 3     def __init__(self,name,age):
 4         self.name=name
 5         self.age=age
 6     def func(self):
 7         ...
 8 
 9 print(1,Fo.__dict__)
10 """
11 1 {'__module__': '__main__', 
12 'name': 'peter', 
13 '__init__': <function Fo.__init__ at 0x000000000252FAE8>, 
14 'func': <function Fo.func at 0x000000000252FF28>, 
15 '__dict__': <attribute '__dict__' of 'Fo' objects>, 
16 '__weakref__': <attribute '__weakref__' of 'Fo' objects>, 
17 '__doc__': None}
18 """
19 print(2,dir(Fo))
20 """
21 ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
22 '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
23 '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', 
24 '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
25 '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 
26 'func', 'name']
27 """
dict

 

 

博客链接参详

  1 s8day127
  2 
  3 内容回顾:
  4     1. django/flask框架的认识?
  5     
  6     2. Flask上下文管理机制
  7         PS: 类
  8         
  9     3. 为什么把请求放到RequestContext中:
 10         ctx = RequestContext(request,session)
 11     4. Local对象作用?
 12         - 看过Local源码,threading.local相似,但是又有不同之处。
 13         - Local中基于greenlet获取唯一标识,粒度更细。
 14     5. LocalStack对象作用?
 15         - 对Local对象中的数据进行操作。
 16         - 将local对象中的数据维护成一个栈
 17             local = {
 18                 1231:{stack: [ctx,]}
 19             }
 20     6. 上下文管理
 21         请求上下文:request/session
 22          App上下文: app/g
 23     7. 什么是g?
 24     
 25     8. 获取Session/g/current_app/request 
 26         
 27     9. 技术:
 28         - 反射 
 29         - 面向对象,封装:RequestContext
 30             __dict__
 31         - 线程(threading.local)
 32         - 笔试:自己写一个类+列表 实现栈。(LocalStack,文杰)
 33     
 34     PS: 一定要会
 35     
 36 今日内容:
 37     1. flask-session 
 38     
 39     2. 数据库连接池:DBUtils(pymysql)
 40     
 41     3. wtforms
 42     
 43     4. SQLAchemy/flask-sqlachemy
 44     
 45     5. flask-script
 46     
 47     6. flask-migrate
 48     
 49 内容概要:
 50     0. 补充:视频播放
 51     
 52     1. flask-session 
 53         作用:将默认保存的签名cookie中的值 保存到 redis/memcached/file/Mongodb/SQLAlchemy
 54         
 55         应用:
 56             a. 配置
 57                 app.config['SESSION_TYPE'] = 'redis'
 58                 app.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='6379')
 59                 
 60             b. 替换 
 61                 from flask_session import Session
 62                 Session(app)
 63                 
 64             注意:session中存储的是字典,修改字典内部元素时,会造成数据不更新。
 65                   - motified = True
 66                   - SESSION_REFRESH_EACH_REQUEST = True and  session.permanent = True(redis中默认)
 67         
 68         
 69         PS: 
 70                  数据框 模板      视图
 71             MTV, Model  Template  View
 72             MVC, Model  View      Controller
 73     
 74     2. 数据库连接池
 75         pip install DBUtils
 76         
 77         模式:
 78             - 每个线程创建一个连接,关闭(默认不关闭),线程终止时,才关闭连接。
 79             - 创建共享连接池
 80         
 81         应用:只要写原生SQL,用户数据框连接池
 82         
 83         
 84         
 85     3. wtforms 
 86         作用:用于对python web框架做表单验证。
 87         
 88         使用:
 89             class MyForm(Form):
 90                 user = 类(正则,插件)
 91                 字段 = 类(正则,插件)
 92                 字段 = 类(正则,插件)
 93                 字段 = 类(正则,插件)
 94                 字段 = 类(正则,插件)
 95                 字段 = 类(正则,插件)
 96                 
 97             
 98             form = MyForm()
 99             # 生成HTML标签
100             print(form.user) 类.__str__ ==> 插件.xx方法
101     
102             # 验证 
103             form = MyForm(formdata=request.form)
104             if form.validate():
105                 # 内部找到所有的字段:user + 用户发过来的数据 =》 正则校验
106     
107         基本使用:
108             http://www.cnblogs.com/wupeiqi/articles/8202357.html
109     
110     
111     
112 总结:
113     1. 授权播放
114     2. flask-session 
115     3. dbutils
116     4. wtforms 
117         - 未完待续
118     
119     作业:
120         - 上下文管理
121         - flask-session
122         - 路飞完成
123         
124         - wtforms
125             - user = simple.StringField() 
126                      UnboundField(simple.StringField,计数器)
127             
128             - FormMeta.__call__
129         
130         - 自己写类实现栈
131         
132 
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155 
156 
157 
158 
159 
160 
161 
162 
163 
164 
165 
166     
167     
168     
169     
170     
171     
172     
173     
174     
175     
176     
177     
178     
179     
180     
181     
182     
183     
184     
185     
186     
187     
188     
189     
190     
191     
192     
193     
194     
195     
196     
197     
198     
199     
200     
201     
202     
203     
204     
205     
206     
207     
208     
209     
210     
211     
212     
213     
214     
215     
216     
217     
218     
219     
220     
221     
222     
223     
224     
225     
226     
227     
228     
229     
230     
231     
232     
233     
234     
235     
236     
237     
238     
View Code

 

 

 

这里是基于蓝图创建的flask项目

蓝图的创建步骤,

一个文件夹,然后在里面再创建一个文件夹,这两者要同名,

在最外层的文件夹里面创建一个manage文件,还有一个settings文件

在里面的这层同名的文件夹里面创建templates文件夹,存放我们的HTML模板,

还有自定义的组件/模块,

还有views文件夹,里面是视图函数

 

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>用户登录</title>
 8 </head>
 9 <body>
10 <form method="post">
11     {{form.user}} {{form.user.errors[0]}}
12     {{form.pwd}}  {{form.pwd.errors[0]}}
13     <input type="submit" value="提交">{{msg}}
14 </form>
15 </body>
16 </html>
templates

 

 1 import pymysql
 2 from settings import BaseConfig
 3 
 4 
 5 class SQBase():
 6     @staticmethod
 7     def open(cursor):
 8         POOL = BaseConfig.SQL_POOL
 9         conn = POOL.connection()
10         cursor = conn.cursor(cursor=cursor)  # 这里等号右边的cursor是我们的形参,传入的值
11         return conn, cursor
12 
13     @staticmethod
14     def close(conn, cursor):
15         conn.commit()
16         cursor.close()
17         conn.close()
18 
19     @classmethod
20     def fetch_one(cls, sql, args, cursor=pymysql.cursors.DictCursor):
21         conn, cursor = cls.open(cursor)
22         cursor.execute(sql, args)
23         obj = cursor.fetchone()
24         cls.close(conn, cursor)
25         return obj
26 
27     @classmethod
28     def fetch_all(cls, sql, args, cursor=pymysql.cursors.DictCursor):
29         conn, cursor = cls.open(cursor)
30         cursor.execute(sql, args)
31         obj = cursor.fetchall()
32         cls.close(conn, cursor)
33         return obj
utils(自定义组件)

 

 1 from flask import request, redirect, render_template, Blueprint, session
 2 from wtforms import Form
 3 from ..utils.demo import SQBase
 4 from wtforms import simple, validators, widgets
 5 
 6 acc = Blueprint('account', __name__)
 7 
 8 
 9 class LoginForm(Form):
10     user = simple.StringField(
11         validators=[
12             validators.DataRequired(message='用户名不能够为空'),
13         ],
14         widget=widgets.TextInput(),
15         render_kw={'class': 'form-control', 'placeholder': 'user'}  # 这是给我们的前端标签添加属性
16     )
17     pwd = simple.PasswordField(
18         validators=[
19             validators.DataRequired(message='密码不能为空'),
20         ],
21         widget=widgets.PasswordInput(),
22         render_kw={'class': 'form-control', 'placeholder': 'pwd'}
23     )
24 
25 
26 @acc.route('/login', methods=['GET', 'POST'])
27 def login():
28     if request.method == 'GET':
29         form = LoginForm()
30         return render_template('login.html', form=form)
31 
32     form = LoginForm(formdata=request.form)
33     if not form.validate():
34         return render_template('login.html', form=form)
35 
36     fh = SQBase.fetch_one("select id,name from userinfo where name=%(user)s and pwd=%(pwd)s", form.data)
37     if fh:
38         session.permanent = True
39         session['user_info'] = {'id': fh['id'], 'name': fh['name']}
40         return redirect('/index')
41     else:
42         return render_template('login.html', msg='user or pwd is wrong', form=form)
views
 1 from flask import Blueprint,session
 2 hom=Blueprint('index',__name__)
 3 @hom.route('/index')
 4 def index():
 5     user_obj=session.get('user_info')
 6     print('old message',user_obj)
 7     session['user_info']['h1']=798
 8     user_obj=session.get('user_info')
 9     print('new message',user_obj)
10     return 'index'
views1

 

 1 from flask import Flask
 2 from flask_session import Session
 3 from .views import account
 4 from .views import index
 5 
 6 def create_aps():
 7     app=Flask(__name__)
 8     app.config.from_object('settings.DevelopmentConfig')
 9 
10     app.register_blueprint(account.acc)
11     app.register_blueprint(index.hom)
12     # 将session替换成redis session
13     Session(app)
14     return app
__init__
1 from threading_pool import create_aps
2 app=create_aps()
3 if __name__=='__main__':
4     app.__call__
5     app.run()
manage.py
 1 from datetime import timedelta
 2 from redis import Redis
 3 import pymysql
 4 from DBUtils.PooledDB import PooledDB, SharedDBConnection
 5 
 6 
 7 class BaseConfig():
 8     DEBUG = True
 9     SECRET_KEY = 'aslgjkas'
10     PERMANENT_SESSION_LIFETIME = timedelta(minutes=20)
11     SESSION_TYPE = 'redis'
12     SQL_POOL = PooledDB(
13         creator=pymysql,  # 使用链接数据库的模块
14         maxconnections=6,  # 连接池允许的最大连接数,0还有None表示不限制连接数
15         mincached=2,  # 初始化时,连接池中至少创建的空闲的链接,0表示不创建,
16         maxcached=4,  # 连接池中最多闲置的链接,0和None表示不限制,
17         maxshared=3,  # 连接池中最多共享的连接数量,0和None表示共享所有,PS:基本不用这个参数,
18         # 因为pymysql和MySQLdb等模块的threadsafety都是1,所以无论设置这个值为多少,maxcached永远为0,也就是所有链接共享
19         blocking=True,  # 连接池中如果没有可用的链接,是否阻塞等待,
20         maxusage=None,  # 一个连接最多被重复使用的次数,None表示无限次
21         setsession=[],  # 开始会话前执行的命令列表,如['set datestyle to,''', 'set time zone...']
22         ping=0,  # pingMySQL服务端,检查是否服务可用, # 如:0=None=never,
23         # 1=default=whenever it is requested,
24         # 2=when a cursor is created,
25         # 4=when a query is executed,
26         # 7=always
27         host='127.0.0.1',
28         port=3306,
29         user='root',
30         password='123',
31         database='book_list',
32         charset='utf8'
33     )
34 
35 
36 class ProductionConfig(BaseConfig):
37     SESSION_REDIS = Redis(host='192.168.13.184', port='6379')
38 
39 
40 class DevelopmentConfig(BaseConfig):
41     SESSION_REDIS = Redis(host='127.0.0.1', port='6379')
42 
43 
44 class TestingConfig(BaseConfig):
45     ...
settings.py

 

posted @ 2018-05-03 23:00  dream-子皿  阅读(103)  评论(0)    收藏  举报