内容概览
- 请求与响应
- session的使用和原理
- 闪现
- 补充异步
- 请求扩展
- 蓝图
请求与响应
请求对象
"""请求对象,是全局的,需要导入,这个全局的request,在哪个视图函数中,就是当次的request对象"""
from flask import Flask, request
app = Flask(__name__)
@app.route('/index')
def index():
print(request.method)
print(request.args)
print(request.args.get('name'))
print(request.form)
print(request.values)
print(request.cookies)
print(request.headers)
print('------')
print(request.path)
print(request.full_path)
print('服务端:', request.script_root)
print(request.url)
print(request.base_url)
print(request.url_root)
print(request.host_url)
print(request.host)
print(request.files)
print(request.data)
return 'hello'
响应对象
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/',methods=['POST'])
def index():
res='helloe'
res=make_response(res)
res.headers['name']='lqz'
res.delete_cookie('xx')
'''
key, 键
value=’’, 值
max_age=None, 超时时间 cookie需要延续的时间(以秒为单位)如果参数是\ None`` ,这个cookie会延续到浏览器关闭为止
expires=None, 超时时间(IE requires expires, so set it if hasn’t been already.)
path=’/‘, Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问,浏览器只会把cookie回传给带有该路径的页面,这样可以避免将cookie传给站点中的其他的应用。
domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。如, domain=”.example.com”所构造的cookie对下面这些站点都是可读的:www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。如果该参数设置为 None ,cookie只能由设置它的站点读取
secure=False, 浏览器将通过HTTPS来回传cookie
httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
'''
return res
前后端分离和混合
- res.set_cookie('xx','xx') 混合都是这么写的,这样写了,浏览就会把cookie保存到cookie中
-本质是后端把cookie放到响应头中,浏览器读到响应头中有cookie,把cookie写入到浏览器中
-直接把客户端要存到cookie中的数据,放到响应体中
-前端(浏览器,app,小程序),自己取出来,放到相应的位置
浏览器使用js自己写入到cookie
app 自己使用代码写入到某个位置
session的使用和原理

session的使用
导入全局的session
session['name']='lqz'
导入全局的session
print(session['name'])

源码分析
-请求来了,会执行 app()
def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
try:
try:
ctx.push()
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except:
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
ctx.pop(error)
if self.session is None:
session_interface = self.app.session_interface
self.session = session_interface.open_session(self.app, self.request)
if self.session is None:
self.session = session_interface.make_null_session(self.app)
SecureCookieSessionInterface()
-open_session:请求来了,从cookie中取出三段串,反序列化解密放到session中
-save_session:请求走了,把session字典中的值,序列化加密,放到cookie中
def open_session(self, app, request) :
s = self.get_signing_serializer(app)
if s is None:
return None
val = request.cookies.get('session')
if not val:
return self.session_class()
max_age = int(app.permanent_session_lifetime.total_seconds())
try:
data = s.loads(val, max_age=max_age)
return self.session_class(data)
except BadSignature:
return self.session_class()
def save_session(self, app, session, response):
name = self.get_cookie_name(app)
domain = self.get_cookie_domain(app)
path = self.get_cookie_path(app)
secure = self.get_cookie_secure(app)
samesite = self.get_cookie_samesite(app)
httponly = self.get_cookie_httponly(app)
if not session:
if session.modified:
response.delete_cookie(
name,
domain=domain,
path=path,
secure=secure,
samesite=samesite,
httponly=httponly,
)
return
if session.accessed:
response.vary.add("Cookie")
if not self.should_set_cookie(app, session):
return
expires = self.get_expiration_time(app, session)
val = self.get_signing_serializer(app).dumps(dict(session))
response.set_cookie(
name,
val,
expires=expires,
httponly=httponly,
domain=domain,
path=path,
secure=secure,
samesite=samesite,
)
1 请求来的时候,会执行open_session--->取出cookie,判断是否为空,如果不为空,把它反序列化,解密---》字典---》转到session对象中----》视图函数
2 请求走的时候,会执行save_session---->把session转成字典----》序列化加密--》三段---》放到cookie中
闪现
访问a页面,出了错,重定向到了b页面,要在b页面线上a页面的错误信息
在某个请求中放入值,另一个请求中取出,取出来后就没了
设置值:
flash('不好意思,没有权限看')
可以用多次
取值:取出列表
get_flashed_messages()
设置值:
flash('钱钱钱',category='lqz')
flash('666',category='c1')')
可以用多次
取值:取出列表
errors = get_flashed_messages(category_filter=['lqz'])
补充异步
async def index():
print('sdfasd')
a++
await xxx
async def goods():
pass
-pymysql :同步的
-redis :同步
-aiomysql:异步
-aioredis:异步
-在fastapi或sanic中,要操作mysql,redis要使用异步的框架,否则效率更低
-django 3.x 以后页支持async 关键字
-没有一个特别好异步的orm框架
-sqlalchemy在做
-tortoise-orm
https://tortoise-orm.readthedocs.io/en/latest/index.html
import asyncio
import aiomysql
loop = asyncio.get_event_loop()
async def test_example():
conn = await aiomysql.connect(host='127.0.0.1', port=3306,
user='root', password='', db='mysql',
loop=loop)
cur = await conn.cursor()
await cur.execute("SELECT Host,User FROM user")
print(cur.description)
r = await cur.fetchall()
print(r)
await cur.close()
conn.close()
loop.run_until_complete(test_example())
import aioredis
import asyncio
class Redis:
_redis = None
async def get_redis_pool(self, *args, **kwargs):
if not self._redis:
self._redis = await aioredis.create_redis_pool(*args, **kwargs)
return self._redis
async def close(self):
if self._redis:
self._redis.close()
await self._redis.wait_closed()
async def get_value(key):
redis = Redis()
r = await redis.get_redis_pool(('127.0.0.1', 6379), db=7, encoding='utf-8')
value = await r.get(key)
print(f'{key!r}: {value!r}')
await redis.close()
if __name__ == '__main__':
asyncio.run(get_value('key'))
请求扩展
多个的话,会从上往下,依次执行, django:process_request
如果返回四件套之一,就直接返回了
在这里面,正常使用request对象
多个的话,会从下往上,依次执行, django:process_response一样
要有参数,和返回值,参数就是response对象,返回值也必须是resposne对象
session,request 照常使用
向响应头写东西?向cookie中写东西
可以做一些初始化的操作
@app.teardown_request
def tear_down(e):
print(e)
print('我执行了')
@app.errorhandler(500)
def error_500(arg):
print('500会执行我')
return "服务器内部错误"
@app.template_global()
def sb(a1, a2):
return a1 + a2
@app.template_filter()
def db(a1, a2, a3):
return a1 + a2 + a3
蓝图
-1 在不同的view的py文件中,定义蓝图
-2 使用app对象,注册蓝图
-3 使用蓝图,注册路由,注册请求扩展
flask_blueprint
-static
-templates
-user.html
-views
-__init__.py
goods.py
user.py
app.py
flask_blueprint_little
-src
-__init__.py
-templates
-user.html
-static
-views
-user.py
-order.py
-manage.py
flask_blurprint_big
-src
-__init__.py
-settings.py
-admin
-__init__.py
-template
-backend.html
-static
-xx.jpg
-views.py
-models.py
-api
-__init__.py
-template
-static
-models.py
-views.py
-manage.py
from flask import Flask, Blueprint
app = Flask(__name__)
user_bp = Blueprint('user', __name__)
app.register_blueprint(user_bp)
@user_bp.route('/user')
def user():
return render_template('user.html')