【python之django1.11框架六】django中间件

1. django中间件

  • django中间件是django的门户
    1.请求来的时候需要先经过中间件才能到达真正的django后端
    2.响应走的时候最后也需要经过中间件才能发送出去
# 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支持自定义中间件并且暴露五个可以自定义的方法

  1. 必须掌握

    • process_request
    1. 请求来的时候需要经过每一个中间件里面的process_request方法
      结果的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行

    2. 如果中间件里面没有定义该方法,那么直接跳过执行下一个中间件

    3. 如果该方法返回了HttpResponse对象,那么请求将不再继续往后执行
      而是直接原路返回(校验失败不允许访问…)

      process_request方法就是用来做全局相关的所有限制功能

    • process_response
    1. 响应走的时候需要结果每一个中间件里面的process_response方法
      该方法有两个额外的参数request,response

    2. 该方法必须返回一个HttpResponse对象

      1. 默认返回的就是形参response
      2. 你也可以自己返回自己的
      3. 顺序是按照配置文件中注册了的中间件从下往上依次经过
        如果你没有定义的话 直接跳过执行下一个

      研究如果在第一个process_request方法就已经返回了HttpResponse对象,那么响应走的时候是经过所有的中间件里面的process_response还是有其他情况?
      就是会直接走同级别的process_reponse返回

  2. 了解方法

    • process_view
      路由匹配成功之后执行视图函数之前,会自动执行中间件里面的该方法
      顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
    • process_template_response
      返回的HttpResponse对象有render属性的时候才会触发
      顺序是按照配置文件中注册了的中间件从下往上依次经过
    • process_exception
      当视图函数中出现异常的情况下触发
      顺序是按照配置文件中注册了的中间件从下往上依次经过

1.1 如何自定义中间件

"""
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',
]
"""

1.2 CsrfViewMiddleware 中间件介绍

  • 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')

2. importlib 模块介绍

# 模块:importlib
import importlib
res = 'myfile.b'
ret = importlib.import_module(res)  # 等同于执行了 from myfile import b
# 该方法最小只能到py文件名
print(ret)

2. 1 可配置插拔式设计思想

通过配置文件配置相应的功能,实现在配置文件中配置过对应功能模块,则生效;注释对应模块,则不生效。

# 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('快下课了') # 配置文件中配置了哪些功能,哪些功能则生效
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值