25 Jun 18 Django,中间件

26 Jun 18

一、上节课复习

1. Cookie(保存在浏览器端的键值对)

    应用:

    a. 登录

    b. 记住密码/7天免登录

    c. 用户浏览习惯(每页显示10条)

    d. 简单的投票限制

 

       Cookie,作用于响应。设置rep.set_cookie("key","value"); 获取request.COOKIES.get("key","")

 

   request.COOKIES["key"]  #不推荐,没有报错

    request.COOKIES.get("key", "")  # 若没有,返回"";不加第二个参数,没有报错

    request.get_signed_cookie("key", default="", salt="shanghais1hao")  # 若没有,走default;不加default,没有报错

 

2. Session (保存在服务端的键值对,依赖于Cookie)

    应用:

    a. 登录

    b. 保存手机验证码/验证码

    c. 保存购物车数据

 

    session,作用于响应,设置和获取都用request

 

    request.session.set_expiry(秒/日期对象/时间间隔对象/0/None)  #如果参数是None,默认两周

    request.session.clear_expired()  # 手动清除早已经过期的session数据

 

    相关配置项(写在settings.py中的)

    a. SESSION_SAVE_EVERY_REQUEST = True  #每次请求都更新Session失效时间

    b. SESSION_COOKIE_AGE = 1209600      # 设置Cookie超时时间

    c. SESSION_COOKIE_NAME = "sessionid"# Session的cookie保存在浏览器上时的key

    d. 其他:

        SESSION_COOKIE_PATH ="/"       # Session的cookie保存的路径(默认)

        SESSION_COOKIE_DOMAIN = None     # Session的cookie保存的域名(默认)

        SESSION_COOKIE_SECURE = False    # 是否Https传输cookie(默认)

       SESSION_COOKIE_HTTPONLY = True   #是否Session的cookie只支持http传输(默认)

 

二、今日内容(中间件)

https://www.cnblogs.com/liwenzhou/p/8761803.html

 

1. 中间件概念:是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

   中间件缺点:中间件为全局修改,若设置太过复杂的中间件,会降低效率影响性能

 

2. settings.py  -> MIDDLEWARE配置项

    # 中间件:配置项为列表(有序);每个字符串是一个类,也就是一个中间件

    MIDDLEWARE = [

       'django.middleware.security.SecurityMiddleware',  #安全校验相关

        'django.contrib.sessions.middleware.SessionMiddleware',  

# 必须放在request.session前,否则request中没有session属性,进而报错

# Django中的request传递的是同一个request

       'django.middleware.common.CommonMiddleware',  # 通用

       'django.middleware.csrf.CsrfViewMiddleware',  # 校验csrf_token

       'django.contrib.auth.middleware.AuthenticationMiddleware',  # 认证相关

        'django.contrib.messages.middleware.MessageMiddleware',  # 信息相关

       'django.middleware.clickjacking.XFrameOptionsMiddleware',

        'mymiddlewares.mm.M1',  #自定义的,可以是一个package中的py文件

        'mm.M2',  #自定义的,可可以一个放在根目录下的py文件

    ]

 

3. 如何自定义中间件

a. 按照格式要求写一个类(放在根目录下的py文件,或者跟目录下新建的package中的py文件中)

        from django.utils.deprecation import MiddlewareMixin

        class MD1(MiddlewareMixin):  # 继承MiddlewareMixin的类

            def process_request(self, request):

               print("MD1里面的process_request")

 

            def process_response(self, request, response):

               print("MD1里面的process_response")

                return response  # process_response必须要用返回值

 

            def process_view(self, request, view_func, view_args, view_kwargs):

                print("MD1 中的process_view")

               print(view_func, view_func.__name__) # .__name__取方法名/函数名

 

            def process_exception(self, request, exception):

               print(exception)

               print("MD1 中的process_exception")

                # return HttpResponse(str(exception))

 

            def process_template_response(self, request, response):

               print("MD1 中的process_template_response")

                return response

 

    b. 把我们写好的类在settings.py注册到MIDDLEWARE配置项的列表中

 

4. 每一个中间件中五个可以被重写的方法:

    a. process_request(self,request)

    1)何时执行:在urls.py之前执行

    2)执行的顺序:按照在列表中注册的顺序依次执行

    3)返回值:

       #1 返回None, 不做任何处理直接进行下一步

       #2 返回响应对象, 直接跳出(后续中间件的process_request、不执行urls.py和views.py)返回同级中间件以及之前(根据列表)的响应

 

    b. process_view(self, request, view_func, view_args, view_kwargs)

        1)执行时间:在urls.py之后,在执行真正的视图函数之前

        2)执行顺序:按照在列表中注册的顺序依次执行

        3)返回值

           #1 返回None, 放行

           #2 返回响应对象,就直接跳出,倒序依次执行所有中间件的process_response方法

 

    c. process_response(self, request, response)

        1)何时执行:在views.py返回响应对象之后执行

        2)执行的顺序:按照在列表中注册的倒序依次执行

        3)返回值:必须要有返回值,否则报错。返回要是响应对象(HttpResponse, render, redirect), 可能是views中的响应,也可能是MIDDLEWARE中其之后(根据列表)的process_response的响应

 

    d. process_exception(self, request, exception)

       1)何时执行:只有在视图函数中出现异常了才执行

       2)执行的顺序:按照中间件注册顺序的倒序执行

       3)返回值:

          #1 返回一个None,交给下一个中间件的process_exception方法来处理异常。

          #2 返回HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。

          # 例如: 中间件M1在M2之前(根据列表),如果出现exception,M2的的process_exception会被触发,若其有返回值,M1中的process_exception不会被执行

 

    e. process_template_response(self,request,response)(用的比较少)

       1)何时执行: 当response是TemplateResponse对象(由视图函数或者中间件产生);视图函数返回的对象有render()方法。process_template_response是在视图函数执行完成后立即执行。

       2)执行的顺序:按照中间件注册顺序的倒序执行

       3)返回值:None/ Response

 

5. 中间件的执行流程

三、例子

mm.py

from django.utils.deprecation import MiddlewareMixin

from django.shortcuts import HttpResponse, redirect

 

class M1(MiddlewareMixin):

    """

    五个支持被重写的方法

    1. process_request(self,request)

    2. process_view(self, request, view_func, view_args, view_kwargs)

    3. process_template_response(self,request,response)

    4. process_exception(self, request, exception)

    5. process_response(self, request, response)

    """

    # 取代views中的装饰器,通过设置中间件process_request为每个视图加上验证功能

    def process_request(self,request):

        print("哈哈哈,我是自定义中间件M1中的一个卖报的小行家!")

        next_url = request.path_info

        if not request.path_info.startswith("/login/"):  # 排除login页面

            login_flag = request.session.get("login", "")

            if not login_flag:

                rep = redirect("/login/?next={}".format(next_url))

                return rep

 

    def process_view(self, request, view_func, view_args, view_kwargs):

        print("这是m1中的process_view方法")

       print(view_func.__name__)

 

    # 捕捉异常

    def process_exception(self, request, exception):

        print("我是m1里面的process_exception")

        if isinstance(exception, ValueError):  #如果捕捉的异常是ValueError的一个实例

            print(exception)

            return HttpResponse("404")

 

    def process_response(self, request, response):

        """

        :param request: 本次请求

        :param response: 响应

        :return:

        """

        print("m1中的process_response方法")

        return response  #必须要有response

        # rep = HttpResponse("O98K")

        # return rep

 

四、其他

1. 以下两个导入方式导入的HttpResponse是一个

    from django.http import HttpResponse

    from django.shortcuts import  HttpResponse

 

2. Django中的request传递的是同一个request

 

3. importlib(字符串-> 导入对应的模块/包)

https://pymotw.com/3/py-modindex.html

#1 importlib.machinery(): to find the supported types for the current platform, and the parameters for loading them.

 

#2 importlib.import_module(): mport a module given an absolute or relative name; If the module cannot be imported, import_module() raises ImportError.

 

#3 importlib.reload(): to reload an existing module

 

#4 importlib.find_loader(): to get a loader for a module

 

#5 loader = importlib.find_loader('example')

loader.load_module(): to retrieve the module

 

4. 时间间隔

猜你喜欢

转载自www.cnblogs.com/zhangyaqian/p/py20180626.html
今日推荐