django中间件补充、django操作cookie与session
目录基于django中间件实现功能的插拔式设计
在使用自定义中间件时可以注意到,通过注册来启动或关闭一个功能十分便捷,这种方式被称为功能的插拔式设计。
使用方式:
1.将各个功能制作成配置文件的字符串形式;
2.想拥有该功能就编写对应的字符串;
3.不想有该功能则注释对应的字符串即可。
# 使用importlib模块模仿django中间件调用功能的方式
importlib可以帮忙用字符串导入模块,拿到模块名的字符串,importlib可以搜索模块并执行导入操作:
import importlib # 引入模块
s1 = 'bbb.b' # aaa.bbb.ccc.b
res = importlib.import_module(s1) # from aaa.bbb.ccc import b
print(res) # <module 'bbb.b' from 'D:\\pythonProject03\\djangomiddle\\bbb\\b.py'>
s2 = 'aaa'
res=importlib.import_module(s2)
# 相当于import aaa 并将模块设置为res
'''注意字符串的结尾最小单位只能是py文件 不能是py文件里面的变量名'''
# 功能模拟——编写一个消息通知功能(微信、QQ、邮箱)
实现方式1:基于函数封装的版本
def qq(content):
print('来自qq的消息:%s', % content)
def wechat(content):
print('来自微信的消息:%s', % content)
def email(content):
print('来自邮箱的消息:%s', % content)
def send_all(content):
# qq(sontent) 不想发哪个消息就注释哪个函数
wechat(content)
email(content)
if __name__ == 'main':
send_all('元旦三天假 你想怎么过?')
使用函数封装三个发送消息的应用,用启动函数运行。当不想执行某个应用的消息通知功能时,就将这个应用的此功能在启动函数中对应的调用代码注释掉即可。
缺点:很一般,毫无新意
实现方式2:基于django中间件的功能设计
1.importlib
通过字符串导入模块
2.从右开始切割字符串
rsplit
3.反射
将模块名看成是对象通过反射回去该模块中字符串对应的名字
4.面向对象的多态性
优点: 眼前一亮,回味无穷
# 模块对象的反射
python中一切皆对象,模块也是一种对象。模块的名称空间中的名字就是模块对象的属性。所以对于一个模块,我们可以通过反射的方式取到其中的类、函数、变量等名字。
# 仿django配置文件注册
# MyMiddleWare文件夹midware01.py中
class MidWare01(MiddlewareMixin):
def process_request(self, request):
print('from MidWare01 request')
# MyMiddleWare文件夹midware02.py中
class MidWare02(MiddlewareMixin):
def process_request(self, request):
print('from MidWare01 request')
# 注册配置
MIDWARE_LIST = [
'MyMiddleWare.midware01.MidWare01',
'MyMiddleWare.midware02.MidWare02',
]
# 按照注册顺序,执行每个类中的process_request方法
import importlib
def all_exec(request):
for full_path in MIDWARE_LIST:
# 将字符串切割为模块路径和类名
path, cls_name = full_path.rsplit('.', max_split=1)
# 通过模块路径字符串拿到模块名
module_name = importlib.import_module(path)
# 通过模块名反射拿到类名
cls = getattr(module_name, cls_name)
# 通过类产生对象
obj = cls()
# 通过对象使用方法
obj.process_request(request)
# 多态的思想,因为大家的这个功能一致,所以方法名也该一致
cookie与session简介
HTTP协议四大特性:
1.基于请求响应
2.基于TCP、IP作用于应用层之上的协议
3.无状态,不保存客户端的状态
4.无连接
需求变化:
最开始的网站都不需要用户注册,所有人来访问获取到的数据都是一样的;
随着互联网的发展,很多网站需要指定当前用户的状态,因此需要用到cookie和session
cookie
保存在客户端,存储与用户状态相关的信息
session
保存在服务端,存储与用户状态相关的信息
# session的工作需要依赖于cookie
补充:
浏览器有资格拒绝保存服务端发送过来的cookie数据(需要在设置里设置,但都拒绝的话会出现不能登陆的情况)
可以在浏览器中右键检查查看cookies信息,如果主动删除这些cookies信息就需要重新登陆。但若短时间频繁操作,可能被某些网页检测到导致被封ip
django操作cookie
from django.shortcuts import render,HttpResponse,redirect
return render()
return HttpResponse()
return redirect()
要想操作cookie就不能直接返回HttpResponse对象 必须先用变量接收
obj1 = render()
return obj1
obj2 = HttpResponse()
return obj2
obj3 = redirect()
return obj3
# 用户登录功能
用户未登录想访问某个网站,输入用户名密码之后就应该调回该网站
def login_func(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'jason' and password == '123':
target_path = request.GET.get('next')
if target_path:
obj = redirect(target_path)
else:
obj = redirect('/home/')
obj.set_cookie('name', username)
return obj
return render(request, 'loginPage.html')
def login_auth(func_name):
def inner(request, *args, **kwargs):
print(request.path)
# 只获取用户输入的路由信息
print(request.path_info)
# 只获取用户输入的路由信息
'''request.path和request.path_info都能拿到请求页面的路由,这样我们就能记录下是哪个页面想服务端发送了请求'''
target_path = request.path_info
print(request.get_full_path())
# 获取用户输入的路由信息+问号后面携带的数据
if request.COOKIES.get('name'):
res = func_name(request, *args, **kwargs)
return res
'''将路由拼接在/login/?的后面,在登录界面可以将路由拿到并进行跳转'''
return redirect('/login/?next=%s' % target_path)
return inner
# 退出登录本质就是将客户端的标识用户身份的cookie删除掉
django操作session
session是保存在服务端上面的数据就应该有个地方能够存储,我们只需要执行数据库迁移命令即可,django会自动创建很多需要的表。
django默认的session失效时间是14天。
# 设置session
语法结构:request.session['key']=value
def session_func(request):
request.session['session的键'] = '今天疯狂星期四'
return HttpResponse('session_func')
设置session时会执行下列操作:
1.当执行request.session['key']=value之后,首先生成一个随机字符串,就是session_key;
2.对value做加密处理,django会在django_session表中存储session_key以及session_data的对应关系。session_data对应的就是我们添加的值'今天疯狂星期四';
3.将随机字符串session_key发送一份给cookie。
此后登陆服务端session会校验用户是否有该字符串,如果有的话在一定时间内就可以不用登录。
# 获取session
语法结构:request.session.get('key')
def session_get(request):
print(request.session.get('session的键'))
return HttpResponse('session_get') # 今天疯狂星期四
获取session时会执行下列操作:
1.自动获取客户端携带的加密字符串
2.自动去django_session表中根据随机字符串获取加密的数据
(比对是否有对应记录)
3.如果有自动获取加密的数据并解密到request.session.get()中
# 补充说明
1.可以设置过期时间
2.存储session数据的位置也可以修改
# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
# 检查会话session的key在数据库中是否存在
request.session.exists("session_key")
# 删除当前会话的所有Session数据
request.session.delete()
# 删除当前的会话数据并删除会话的Cookie。
request.session.flush()
# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效;
* 如果value是个datatime或timedelta,session就会在这个时间后失效;
* 如果value是0,用户关闭浏览器session就会失效;
* 如果value是None,session会依赖全局session失效策略。
标签:中间件,request,django,session,cookie,模块,path
From: https://www.cnblogs.com/zhiliaowang/p/17025536.html