zoukankan      html  css  js  c++  java
  • 第5天:基于类的视图与中间件

    •  类视图引入
    •  类视图的定义与使用
    •  类视图实现的原理
    •  在类视图中使用装饰器
    •  类视图多继承&Minx扩展类
    •  中间件

    类视图引入

    以函数的方式定义的视图成为函数视图,函数视图便于理解。但是遇到一个视图对应的路径提供了多种不同HTTP请求方式的支持时,就需要在一个函数中编写不同的业务逻辑,代码可读性与复用性都不佳

    def register(request):
        """处理注册"""
    
        #获取请求方法,判断是GET/POST请求
        if request.method == 'GET':
            #处理GET请求,返回注册页面
            return render(request, 'register.html')
        else:
            #处理POST请求,实现注册逻辑
            return HttpResponse('这里实现注册逻辑')
    函数视图示例

    在Django中也可以使用类来定义一个视图,称为类视图

    def register(View):
        """类视图 处理注册"""
        
        def get(self, request):
            "处理GET请求, 返回注册页面"
            return render(request, 'register.html')
        
        def post(self, request):
            " 处理POST请求,实现注册逻辑"
            return HttpResponse('这里实现注册逻辑')
    类视图示例

    类视图好处:

    • 代码可读性好
    • 类视图相对于函数视图通过继承具有更高的可复用性

    类视图的定义与使用

    我们要想使用类视图必须继承View

    from django.views.generic import View

    from django.views.generic import View
    
    
    class DemoView(View):
        def get(self, request):
            return HttpResponse('get page')
        
        def post(self, request):
            return HttpResponse('post page')
    DemoView

    路由那里,我则需要使用该视图的as_view方法转换为函数

    from .views import DemoView
    
    urlpatterns = [
        url(r'^demo/$', DemoView.as_view(), name='demo')
    ]
    路由配置

    类视图实现的原理

     按住ctrl,点击as_view

    @classonlymethod
    def as_view(cls, **initkwargs):
        """
        Main entry point for a request-response process.
        """
        ...
    
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)     #cls就是DemoView类,生成对象
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.request = request
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)
        view.view_class = cls
        view.view_initkwargs = initkwargs
    
        update_wrapper(view, cls, updated=())
    
        update_wrapper(view, cls.dispatch, assigned=())
        return view   #最终还是返回函数
    
    def dispatch(self, request, *args, **kwargs):
        ..
            #根据请求方法判断
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
    相关源码

    在类视图中使用装饰器

    我们知道在函数视图中,可以如下使用装饰器 

    def my_decorator(view_func):
        def wrapper(*args, **kwargs):
            print('装饰器被调用')
            return view_func(*args, **kwargs)
        return wrapper
    
    @my_decorator
    def func_demo(request):
        return HttpResponse('func_demo')
    函数视图使用装饰器

    在类视图中使用为函数视图准备的装饰器时,不能直接添加装饰器,需要使用method_decorator将其转换为适用于类视图方法的装饰器。

     

    类视图多继承& Minx扩展类

    使用面向对象多继承特性,可以通过定义父类(作为扩展类),在父类中定义想要想类视图补充的方法,类视图继承这些扩展类,便可实现代码服用。定义父类名称通常以Mixin结尾

    class ListModelMixin(object):
        """list扩展类"""
        def list(self, request, *args, **kwargs):
            print('查询多条数据')
    
    
    class CreateModelMixin(object):
        """create扩展类"""
        def create(self, request, *args, **kwargs):
            print('新增一条数据')
    
    
    class DepartmentView(CreateModelMixin, ListModelMixin, View):
        """
        同时继承两个扩展类,复用list和create方法
        """
        def get(self, request):
            self.list(request)
            return HttpResponse('get page')
    
        def post(self, request):
            self.create(request)
            return HttpResponse('post page')
    示例

    中间件

    Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。我们可以可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预。

    1、定义一个中间件,在项目中新建一个middlewares.py文件,然后在该文件中定义中间件类:

    from django.utils.deprecation import MiddlewareMixin
    
    
    # 定义中间件类: 通过继承Django的MiddlewareMixin扩展类实现
    class MyMiddleware(MiddlewareMixin):
    
        def __init__(self, get_response=None):
            # 服务器启动,初始化中间件类时被调用,只执行一次
            super().__init__(get_response)
            print('init')
    
        def process_request(self, request):
            print('before 视图')
            # 注意:可以返回None或者response对象,如果返回response对象,则视图函数就不会再执行了
    
        def process_response(self, request, response):
            print('after 视图')
            return response
    自定义中间件

    2、在settings.py文件中添加中间件

     

    3、定义一个视图进行测试

    def index(request):
        print('====index===')
        return HttpResponse('hello world')

     

    多个中间件的执行顺序

    #1、再定义一个中间件类
     class MyMiddleware2(MiddlewareMixin):
    
         def __init__(self, get_response=None):
             super().__init__(get_response)
             print('init 2')
    
         def process_request(self, request):
             print('before 视图 2')
    
         def process_response(self, request, response):
             print('after 视图 2')
             return response
    
    #2、注册
     MIDDLEWARE = [
         'django.middleware.security.SecurityMiddleware',
         ...
         'middlewares.MyMiddleware',  # 注册中间件
         'middlewares.MyMiddleware2',  
     ]
    
    #3、执行结果
     before 视图
     before 视图 2
     ==index==
     after 视图 2
     after 视图
    
    #4、结论
    对于视图之前执行的 process_request 方法,先 注册的中间件先执行
    对于视图之后执行的 process_response 方法,后 注册的中间件先执行
    示例说明
  • 相关阅读:
    MVC ORM 架构
    Kubernetes 第八章 Pod 控制器
    Kubernetes 第七章 Configure Liveness and Readiness Probes
    Kubernetes 第六章 pod 资源对象
    Kubernetes 第五章 YAML
    Kubernetes 核心组件
    Kubernetes 架构原理
    Kubernetes 第四章 kubectl
    Kubernetes 第三章 kubeadm
    yum 配置及yum 源配置
  • 原文地址:https://www.cnblogs.com/sellsa/p/10745562.html
Copyright © 2011-2022 走看看