知识点四
1. 谈谈你对django和flask的认识?
django功能强大,内置组件多如orm,form,分页等,更适合用于大项目的开发,flask短小精悍,
可扩展性强,更适合小项目的开发,django和flask都是基于wsgi是实现的,不同点在于django
的request是作为参数引入的,session是依赖request,而flask得request和session是导入进来的
2.什么是wsgi?
web服务网关接口,wsgi是一个协议,实现该写一个的模块:
- wsgiref
- werkzeug
实现其协议的模块本质上就是socket服务端用于接收用户请求,并处理。
一般web框架基于wsgi实现,这样实现关注点分离。
wsgiref示例:
from wsgiref.simple_server import make_server
def run_server(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ]
if __name__ == '__main__':
httpd = make_server('127.0.0.1', 8000, run_server)
httpd.serve_forever()
werkzeug示例:
from werkzeug.wrappers import Response
from werkzeug.serving import run_simple
def run_server(environ, start_response):
response = Response('hello')
return response(environ, start_response)
if __name__ == '__main__':
run_simple('127.0.0.1', 8000, run_server)
Flask源码入口:
from werkzeug.wrappers import Response
from werkzeug.serving import run_simple
class Flask(object):
def __call__(self,environ, start_response):
response = Response('hello')
return response(environ, start_response)
def run(self):
run_simple('127.0.0.1', 8000, self)
app = Flask()
if __name__ == '__main__':
app.run()
3. Flask提供功能
- 配置文件
- 所有配置都在app.config中
- app.config["xx"] = 123
- app.config.from_object("类的路径")
- 应用:importlib、getattr
- django中间件
- rest framework全局配置
- session
- 加密后放置在用户浏览器的cookie中。
- 流程:
- 请求到来
- 视图函数
- 请求结束
- 配置文件
- 闪现
- 基于session实现
- 路由
- 装饰器(带参数)
- 自定义装饰器放下面
- 参数
- url_for
- 视图
- FBV
- 请求和响应
- 请求:request
- 响应: 4种
- 模板
- ...
- 特殊装饰器
- before_first_request
- before_request
- after_request
- template_global()
- template_filter()
- errorhandler(404)
- 中间件
4. 知识点:给你一个路径 “settings.Foo”,可以找到类并获取去其中的大写的静态字段。
-
settings.py
class Foo:
DEBUG = True
TEST = True
xx.py
import importlib
path = "settings.Foo"
p,c = path.rsplit('.',maxsplit=1)
m = importlib.import_module(p)
cls = getattr(m,c)
# 如果找到这个类?
for key in dir(cls):
if key.isupper():
print(key,getattr(cls,key))
5. 路飞总共有几个项目
- 管理后台
- 导师后台
- 主站
6. 路飞主站业务
- 课程
- 课程列表
- 课程详细
- 大纲、导师、推荐课程
- 价格策略
- 章节和课时
- 常见问题
- 深科技
- 文章列表
- 文章详细
- 收藏
- 评论
- 点赞
- 支付
- 购物车(4)
- 结算中心(3)
- 立即支付(1)
知识点:
- redis
- 支付宝
- 消息推送
- 构建数据结构
- 优惠券+贝里+支付宝
- 个人中心
- 课程中心
7. Flask基础:
- 配置文件:反射+importlib
- 路由系统:
- 装饰器 @app.route()
- 参数:url,endpoint,methods
- 加装饰器
- endpoint默认是函数名
- functools.wraps(func) + functools.partial
- 写路由两种方式:
- 装饰器
- add_url_rule
- 自定义支持正则的URL
- session
- 蓝图
- 目录结构划分
- 前缀
- 特殊装饰器
8. 上下文管理
- 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] }
}
- 视图函数:再次去获取
- 关闭
9.第三方组件:
1. flask-session
2. DBUtils
10.第二部分:数据库&前端
1. 什么是响应式布局?
@media(min-width 666px)
2. MySQL数据库
(sqlit数据库没有锁)
- 引擎:
- innodb
开启事务 begin;
加锁 xxxxx for update;
解锁 commit;
支持行锁(只锁一行)
支持表锁(可以锁整张表)
功能多速度慢
支持事务
- 示例:
- 终端:
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
支持表锁(可以锁整张表)
不支持行锁
不支持事务
功能少速度快
- 偏函数
import functools
def index(a1,a2):
return a1 + a2
# 原来的调用方式
# ret = index(1,23)
# print(ret)
# 偏函数,帮助开发者自动传递参数
new_func = functools.partial(index,666)
ret = new_func(1)
print(ret)
- super和执行类的区别?
"""
class Base(object):
def func(self):
print('Base.func')
class Foo(Base):
def func(self):
# 方式一:根据mro的顺序执行方法
# super(Foo,self).func()
# 方式二:主动执行Base类的方法
# Base.func(self)
print('Foo.func')
obj = Foo()
obj.func()
"""
####################################
class Base(object):
def func(self):
super(Base, self).func()
print('Base.func')
class Bar(object):
def func(self):
print('Bar.func')
class Foo(Base,Bar):
pass
# 示例一
# obj = Foo()
# obj.func()
# print(Foo.__mro__)
# 示例二
# obj = Base()
# obj.func()
- 面向对象中特殊方法 setattr/getattr注意事项:
class Foo(object):
def __init__(self):
# self.storage = {}
object.__setattr__(self,'storage',{})
def __setattr__(self, key, value):
print(key,value,self.storage)
obj = Foo()
obj.xx = 123
- 基于列表实现栈
class Stack(object):
def __init__(self):
self.data = []
def push(self,val):
self.data.append(val)
def pop(self):
return self.data.pop()
def top(self):
return self.data[-1]
_stack = Stack()
_stack.push('佳俊')
_stack.push('咸鱼')
print(_stack.pop())
print(_stack.pop())
- 全局变量只有在初次加载时执行
11. flask-session
pip3 install flask-session
掌握:
- 使用
# by luffycity.com
import redis
from flask import Flask,request,session
from flask.sessions import SecureCookieSessionInterface
from flask_session import Session
app = Flask(__name__)
# app.session_interface = SecureCookieSessionInterface()
# app.session_interface = RedisSessionInterface()
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.Redis(host='140.143.227.206',port=6379,password='1234')
Session(app)
@app.route('/login')
def login():
session['user'] = 'alex'
return 'asdfasfd'
@app.route('/home')
def index():
print(session.get('user'))
return '...'
if __name__ == '__main__':
app.run()
- 原理:
- session数据保存到redis
session:随机字符串1:q23asifaksdfkajsdfasdf
session:随机字符串2:q23asifaksdfkajsdfasdf
session:随机字符串3:q23asifaksdfkajsdfasdf
session:随机字符串4:q23asifaksdfkajsdfasdf
session:随机字符串5:q23asifaksdfkajsdfasdf
- 随机字符串返回给用户。
随机字符串
源码:
from flask_session import RedisSessionInterface
今日内容:
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和全局变量一样吗?