django的类视图,CBV
  我们在开始接触django的时候,习惯于使用函数编写视图,即FBV。使用FBV时,我们只需要在路由匹配时,对应的路由下找到这个函数就可以了,这样做看似很和谐,但是有的时候,譬如说,当我们需要根据同一个url请求方法的不同而去执行不同的操作时,如果使用FBV去编写视图,那么我们就需要在视图函数中不断地去执行if request.method=='请求方法' 去判断要去执行什么内容,此时的代码就显得不是很优雅。但是此时如果我们使用CBV的方式来编写视图,同样的需求,代码就会显得优雅很多,下面就让我来介绍一下CBV的具体实现:

在django中使用CBV编写视图:
  1、首先我们自定义的视图类需要继承django.views.View类
  2、在视图类中定义以'请求方法名称小'写为名称的方法,这样在执行不同的请求方法的时候就回去自动执行对应的函数
  3、在路由映射的时候,要执行这个试图类的as_view()方法,注意这个方法继承自django.views.View

示例代码如下:
'views.py'文件:
  from django.views import View
  from django.http import HttpResponse

  class UserInfoView(View):

    def get(self, request, *args, **kwargs):
      return HttpResponse('get user')

    def post(self, request, *args, **kwargs):
      return HttpResponse('post user')

    def delete(self, request, *args, **kwargs):
      return HttpResponse('delete user')

'url.py'文件
  from app import views
  urlpatterns = [
    path('user/', views.UserInfoView.as_view())
  ]

上述示例代码就可以根据同一个url执行不同的方法时去执行不同的操作

CBV实现的源码分析:
  1、请求进来,路由找到试图类并执行as_view方法,执行这个方法时其实会返回一个view函数,因此可以看做请求进来之后会先执行试图类的view方法,源码如下:
  @classonlymethod
  def as_view(cls, **initkwargs):
    for key in initkwargs:
      if key in cls.http_method_names:
        raise TypeError("You tried to pass in the %s method name as a "
                "keyword argument to %s(). Don't do that."
                % (key, cls.__name__))
      if not hasattr(cls, key):
        raise TypeError("%s() received an invalid keyword %r. as_view "
                "only accepts arguments that are already "
                "attributes of the class." % (cls.__name__, key))

    def view(request, *args, **kwargs):
      self = cls(**initkwargs)
      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

  2、从上面的源码中可以看出执行view方法,实际上就是返回self.dispatch方法,也就是说会去执行self.dispatch方法

  3、因为试图类本身没有定义dispatch方法,那么在执行dispatch方法的时候就需要去其父类里面查找,而父类里面的dispatch方法则会根据请求方法的不同基于python类的反射去找到相应的方法,然后执行,这样就会自动实现根据请求方法的不同去执行不同的内容了,dispatch方法的源码如下:
  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)

CBV之添加装饰器:

在我们使用函数试图FBV的时候,如果我们想要给其加上一个装饰器,直接加就可以了,例如,在创建django项目的时候,默认全局使用csrf防护,如果我们想要在某个函数试图上不使用CSRF保护,那么我们可以给这个视图函数直接添加一个装饰器即可,示例代码如下:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def index(request):
return HttpResponse('index')

但是,当我们想要给CBV添加装饰器,那么我们需要做的就不是在其内部的方法上添加,如果和FBV一样直接添加到方法上,那么这不会起任何作用。在CBV上添加装饰器的方法有两种,第一种是重写父类的dispatch方法,并将装饰器添加到dispatch方法上,与此同时在CBV上添加装饰器最好使用django.utils.decorators.method_decorator方法进行包裹。第二种方法则是直接添加在类上,只不过这时你需要使用django.utils.decorators.method_decorator来进行封装。下面的例子是我们在django中针对重要的数据操作,想要实现数据库的事件特性而添加的装饰器:

1、方法一:

from django.utils.decorators import method_decorator
from django.db import transaction class OrderView(View):
@method_decorator(transaction.atomic)
def dispatch(self, request, *args, **kwargs):
return super(OrderView, self).dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs):
pass def post(self, request, *args, **kwargs):
pass def patch(self, request, *args, **kwargs):
pass def delete(self, request, *args, **kwargs):
pass 2、方法二:
from django.utils.decorators import method_decorator
from django.db import transaction @method_decorator(transaction.atomic, name='dispatch')
class OrderView(View):
def get(self, request, *args, **kwargs):
pass def post(self, request, *args, **kwargs):
pass def patch(self, request, *args, **kwargs):
pass def delete(self, request, *args, **kwargs):
pass
 

django类视图简单使用和源码解析的更多相关文章

  1. Appium自动化(11) - 详解 Applications 类里的方法和源码解析

    如果你还想从头学起Appium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1693896.html 前言 Applications 类 ...

  2. rest-framework之视图和源码解析

    视图和源码解析 通过使用mixin类编写视图: from rest_framework import mixins from rest_framework import generics class ...

  3. Dubbo原理和源码解析之服务引用

    一.框架设计 在官方<Dubbo 开发指南>框架设计部分,给出了引用服务时序图: 另外,在官方<Dubbo 用户指南>集群容错部分,给出了服务引用的各功能组件关系图: 本文将根 ...

  4. Dubbo原理和源码解析之“微内核+插件”机制

    github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...

  5. Spring源码解析02:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析

    一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...

  6. Spring源码解析 | 第二篇:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析

    一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...

  7. Go语言备忘录:net/http包的使用模式和源码解析

    本文是晚辈对net/http包的一点浅显的理解,文中如有错误的地方请前辈们指出,以免误导! 转摘本文也请注明出处:Go语言备忘录:net/http包的使用模式和源码解析,多谢!  目录: 一.http ...

  8. Dubbo原理和源码解析之标签解析

    一.Dubbo 配置方式 Dubbo 支持多种配置方式: XML 配置:基于 Spring 的 Schema 和 XML 扩展机制实现 属性配置:加载 classpath 根目录下的 dubbo.pr ...

  9. Go语言备忘录(3):net/http包的使用模式和源码解析

    本文是晚辈对net/http包的一点浅显的理解,文中如有错误的地方请前辈们指出,以免误导! 转摘本文也请注明出处:Go语言备忘录(3):net/http包的使用模式和源码解析,多谢!  目录: 一.h ...

随机推荐

  1. Windows 2008 server + IIS 7 设置身份模拟(ASP.NET impersonation)

    IIS7 与 IIS 6 相比有了很大的改动,原来在 IIS 6 下可以的设置到了 IIS 7 下有的会发生变化.身份模拟的配置上,IIS7 和 IIS6有很大不同,网上IIS6的身份模拟的文章比较多 ...

  2. Keepalived 配置高可用

    VRRP协议及Keepalived原理使用   VRRP 协议即 Virtual Router Redundancy Protocol,虚拟路由器冗余协议, 为了解决局域网内默认网关单点失效的问题.  ...

  3. SAP销售订单屏幕字段控制隐藏,必输等

    1.T-CODE:shd0 创建变式  , 点击确认按钮后,SAP进入下一个屏幕,然后重复上面的操作,直到所有屏幕已完成设置. 如果后续屏幕不需要设置,可点击“退出并保存”按钮.保存后,进入下图所示页 ...

  4. CentOS 7 以上防火墙简单配置

    CentOS 7 版本以上默认的防火墙不是iptables,而是firewalle. 因此CentOS 7 以下的 iptables 的配置不能使用. 查看防火墙状态: systemctl statu ...

  5. 【操作系统作业—lab1】linux shell脚本 遍历目标文件夹和所有文件 | 包括特殊字符文件名的处理

    要求:写一个linux bash脚本来查看目标文件夹下所有的file和directory,并且打印出他们的绝对路径. 运行command:./myDir.sh  input_path  output_ ...

  6. 禁止鼠标点右键 - 防止刷新页面 - 禁止复制 chrome 和 firefox不能复制

    document.oncontextmenu = function () {//点右键,啥反应都没有了 return false; } document.onkeydown = function () ...

  7. IDEA项目启动报Unable to open debugger port (127.0.0.1:51554): java.net.SocketException "socket closed"

    启动报错: Unable to open debugger port (127.0.0.1:51554): java.net.SocketException "socket closed&q ...

  8. DHT11资料

    产品名:温湿度传感器 型号:DHT11 厂商:奥松电子 参数: 相对湿度: 分辨率:0.1%RH        16Bit 精度:25℃  正负 %2 温度: 分辨率:0.1%RH        16 ...

  9. Codeforces 845 C Two TVs

    参考:https://blog.csdn.net/xjh_shin/article/details/77491693 #include <iostream> #include <cs ...

  10. C++ vector二维数组

    C++ 构建二维动态数组 int **p; p = ]; //注意,int*[10]表示一个有10个元素的指针数组 ; i < ; ++i) { p[i] = ]; } 这样就构成10*5的数组 ...