zoukankan      html  css  js  c++  java
  • Django的CBV和FBV

    FBV

    FBV ( function base views ) 就是在视图里面使用函数处理请求。

    CBV

    CBV ( class base views) 就是在视图中使用类处理请求。

    Django 加入 CBV 之后我们可以使用类来写 View。这样做的有点是:

    • 提高了代码的复用性,可以使用面向对象的技术,例如Mixin(多继承)
    • 可以用不同的函数针对不同的 HTTP 方法处理,而不是通过很多的 if 来判断,提高了代码的可读性

    使用class-based-views

    使用 CBV 写GET 方法:

    from django.http import HttpResponse
    from django.views import View
    
    
    class IndexView(View):
        def get(self, request):
            return HttpResponse("ok")

    此时配置 url的时候:

    # urls.py 文件中
    
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/', views.IndexView.as_view()),
    ]
    
    
    # 其中  views.IndexView.as_view() 中的  .as_view() 是固定写法

    Django 的 url 是将一个请求分配给可调用的函数,而不是一个class类。针对这个问题,CBV提供了一个个 as_view()  的静态方法(即类方法),调用这个方法会创建一个类的实例,然后通过实例调用 dispatch() 方法,dispatch() 方法会根据 request 的 method 的不同调用相应的方法来处理 request(如get(),post() 等)。之后又和FBV差不多,要接收 request , 得到一个 response 返回。如果方法没有定义,会抛出 HttpRespondeNotAllowed 异常。

    类的属性可以通过两种方法进行设置:

    # 第一种方法是常见的 python 方法,可以被子类覆盖。
    
    class IndexView(View):
        name = 'xm'
        
        def get(self, request):
            return HttpResponse(self.name)
    
    # 这种方法也可以被子类覆盖
    
    class ChileIndexView(IndexView):
        name = 'xh'
    
    
    
    # 第二种方法是在url中指定类的属性:
    
    urlpatterns = [
        url(r'^index/$', views.IndexVieew.as_view(name='chenchen')), 
    ]

    在使用CBV进行POST请求的时候会被 出现 Forbidden 错误,这是因为在启动 Django 项目的时候会自动进行 csrf 验证。

    解决办法:

    # 全局解决-----> 即注释掉 csrf 中间件
    
    # 局部解决:
    
    # 针对视图函数避免 csrf 验证
        from django.views.decorators.csrf import csrf_exempt
        @ csrf_exempt()
        def post(self, request):
            return HttpResponse("POST")
    
    # 类方法中:
    # 方法一:
    
    from django.shortcuts import render, HttpResponse
    from django.views import View
    from django.views.decorators.csrf import csrf_exempt
    from django.utils.decorators import method_decorator
    
    
    @method_decorator(csrf_exempt, name="dispatch")
    class IndexView(View):
    
        def get(self, request, *args, **kwargs):
            return HttpResponse("OK")
    
        def post(self, request, *args, **kwargs):
            return HttpResponse("POST")
    
    # 方法二:
    
    from django.shortcuts import render, HttpResponse
    from django.views import View
    from django.views.decorators.csrf import csrf_exempt
    from django.utils.decorators import method_decorator
    
    class IndexView(View):
        @method_decorator(csrf_exempt)
        def dispatch(self, request, *args, **kwargs):
            print("hello")
            # 执行父类中的dispatch方法
            ret = super(IndexView, self).dispatch(request, *args, **kwargs)
            print("boy")
            return ret
    
        def get(self, request, *args, **kwargs):
            return HttpResponse("OK")
    
        def post(self, request, *args, **kwargs):
            return HttpResponse("POST")

    使用 Mixin

     首先要明白 Django 引入 CBV 的目的:

      Python 的一大重要特性就是面向对象。CBV 更能体现 python 的面向对象。CBV 是通过 class 的方式来实现视图方法的。

      class 相对于 function 来说,更能利用多态的特点,因此更容易从宏观层面上将项目内比较通用的功能抽象出来,可以理解为一个东西具有多种形态( 的特性 )。CBV 的实现原理大体就是由 url 路由到这个 CBV 之后,通过 CBV 内部的 dispatch 方法进行分发,将 get 请求分发给 cbv.get 方法处理,将 post 请求分发给 cbv.post 方法处理。

      在 Django 中使用 Mixin 来重用代码,一个 View Class 可以继承多个Mixin,但是只能继承一个 View(包括View 的子类),推荐把 View 写在最右边,多个 Mixin 写在左边。

    Mixin

    Mixin

      在设计类的继承关系的时候,通常主线都是单一继承下来的。但是,如果需要“混入”额外的功能,通过多重继承就可以实现,这种设计通常称为Mixin。

      Mixin 的目的就是给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个 Mixin 的功能,而不是设计多层次的复杂的继承关系。

      python 自带的很多库也使用了 Mixin。例如,Python 自带了 TCPServer 和 UDPServer 这两类网络服务,而要同时服务多个用户就必须使用多进程或多线程模型,这两种模型由 ForkingMixin 和 ThreadingMixin 提供。通过组合, 我们就可以创造出合适的服务来。

    比如,编写一个多进程模式的 TCP 服务,定义如下:

    class MyTCPServer(TCPServer, ForkingMixin):
        pass

    编写一个多线程模式的 UDP 服务,定义如下:

    class MyUDPServer(UDPServer, ThreadingMixin):
        pass

    如果想要搞一个更先进的协程模型,可以编写一个 CoroutineMixin:

    class MyTCPServer(TCPServer, CoroutineMixin):
        pass

    这样一来,我们不需要复杂而庞大的继承链,只要选择组合不同的类的功能,就可以快速构造出所需的子类。

    小结

    由于 Python 允许使用多重继承,因此,Mixin 就是一种常见的设计。只允许单一继承的语言(如java)是不能使用 Mixin 的设计的。

  • 相关阅读:
    取消chrome(谷歌浏览器)浏览器下最小字体限制
    函数声明方式及作为值的函数
    常用的正则表达式
    8腾讯云服务器账号密码
    errno -4058 and npm WARN enoent ENOENT 解决方案
    node gyp的问题
    npm 版本问题
    无缘无故出现npm 解析异常的的问题 解决方案
    idea注册码
    以太坊测试网络 账号密码
  • 原文地址:https://www.cnblogs.com/hzhcdhm/p/8746289.html
Copyright © 2011-2022 走看看