# django自带七个中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
django支持自定义中间件并且暴露五个可以自定义的方法
必须掌握
process_request
请求来的时候需要经过每一个中间件里面的process_request方法
结果的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
如果中间件里面没有定义该方法,那么直接跳过执行下一个中间件
如果该方法返回了HttpResponse对象,那么请求将不再继续往后执行
而是直接原路返回(校验失败不允许访问…)
process_request
方法就是用来做全局相关的所有限制功能
process_response
响应走的时候需要结果每一个中间件里面的process_response方法
该方法有两个额外的参数request,response
该方法必须返回一个HttpResponse对象
研究如果在第一个process_request方法就已经返回了HttpResponse对象,那么响应走的时候是经过所有的中间件里面的process_response还是有其他情况?
就是会直接走同级别的process_reponse返回
了解方法
process_view
process_template_response
process_exception
"""
1.在项目名或者应用名下创建一个任意名称的文件夹
2.在该文件夹内创建一个任意名称的py文件
3.在该py文件内需要书写类(这个类必须继承MiddlewareMixin)
然后在这个类里面就可以自定义五个方法了
(这五个方法并不是全部都需要书写,用几个写几个)
4.需要将类的路径以字符串的形式注册到配置文件中才能生效
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'你自己写的中间件的路径1',
'你自己写的中间件的路径2',
'你自己写的中间件的路径3',
]
"""
csrf跨站请求伪造校验
网站在给用户返回一个具有提交数据功能页面的时候会给这个页面加一个唯一标识
当这个页面朝后端发送post请求的时候 我的后端会先校验唯一标识,如果唯一标识不对直接拒绝(403 forbbiden)如果成功则正常执行
csrf相关装饰器
"""
1.网站整体都不校验csrf,就单单几个视图函数需要校验
2.网站整体都校验csrf,就单单几个视图函数不校验
"""
from django.views.decorators.csrf import csrf_protect,csrf_exempt
from django.utils.decorators import method_decorator
"""
csrf_protect 需要校验
针对csrf_protect符合我们之前所学的装饰器的三种玩法
csrf_exempt 忽视校验
针对csrf_exempt只能给dispatch方法加才有效
"""
# @csrf_exempt
# @csrf_protect
def transfer(request):
if request.method == 'POST':
username = request.POST.get('username')
target_user = request.POST.get('target_user')
money = request.POST.get('money')
print('%s给%s转了%s元'%(username,target_user,money))
return render(request,'transfer.html')
from django.views import View
# @method_decorator(csrf_protect,name='post') # 针对csrf_protect 第二种方式可以
# @method_decorator(csrf_exempt,name='post') # 针对csrf_exempt 第二种方式不可以
@method_decorator(csrf_exempt,name='dispatch')
class MyCsrfToken(View):
# @method_decorator(csrf_protect) # 针对csrf_protect 第三种方式可以
# @method_decorator(csrf_exempt) # 针对csrf_exempt 第三种方式可以
def dispatch(self, request, *args, **kwargs):
return super(MyCsrfToken, self).dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('get')
# @method_decorator(csrf_protect) # 针对csrf_protect 第一种方式可以
# @method_decorator(csrf_exempt) # 针对csrf_exempt 第一种方式不可以
def post(self,request):
return HttpResponse('post')
importlib
模块介绍# 模块:importlib
import importlib
res = 'myfile.b'
ret = importlib.import_module(res) # 等同于执行了 from myfile import b
# 该方法最小只能到py文件名
print(ret)
通过配置文件配置相应的功能,实现在配置文件中配置过对应功能模块,则生效;注释对应模块,则不生效。
# settings.py
NOTIFY_LIST = [
'notify.email.Email',
'notify.qq.QQ',
'notify.wechat.Wechat',
# 'notify.msg.Msg',
]
# notify目录下
# notify/__init__.py
import settings
import importlib
def send_all(content):
for path_str in settings.NOTIFY_LIST: #'notify.email.Email'
module_path,class_name = path_str.rsplit('.',maxsplit=1)
# module_path = 'notify.email' class_name = 'Email'
# 1 利用字符串导入模块
module = importlib.import_module(module_path) # from notify import email
# 2 利用反射获取类名
cls = getattr(module,class_name) # Email、QQ、Wechat
# 3 生成类的对象
obj = cls()
# 4 利用鸭子类型直接调用send方法
obj.send(content)
# notify/email.py
class Email(object):
def __init__(self):
pass
def send(self, content):
print('邮箱通知:%s' % content)
# notify/wechat.py 其他功能类似
class Wechat(object):
def __init__(self):
pass
def send(self,content):
print('微信通知:%s'%content)
# 使用
import notify
notify.send_all('快下课了') # 配置文件中配置了哪些功能,哪些功能则生效