django类视图简单使用和源码解析

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)

原文地址:https://www.cnblogs.com/limaomao/p/9638127.html

时间: 2024-10-11 11:35:17

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

rest-framework之视图和源码解析

视图和源码解析 通过使用mixin类编写视图: from rest_framework import mixins from rest_framework import generics class BookViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializers

Google Test(GTest)使用方法和源码解析——模板类测试技术分析和应用

写C++难免会遇到模板问题,如果要针对一个模板类进行测试,似乎之前博文中介绍的方式只能傻乎乎的一个一个特化类型后再进行测试.其实GTest提供了两种测试模板类的方法,本文我们将介绍方法的使用,并分析其实现原理.(转载请指明出于breaksoftware的csdn博客) 应用 GTest将这两种方法叫做:Typed Tests和Type-Parameterized Tests.我觉得可能叫做简单模式.高级模式比较通用.先不管这些名字吧,我们看看怎么使用 简单模式(Typed Tests) 首先我们

Google Test(GTest)使用方法和源码解析——参数自动填充技术分析和应用

在我们设计测试用例时,我们需要考虑很多场景.每个场景都可能要细致地考虑到到各个参数的选择.比如我们希望使用函数IsPrime检测10000以内字的数字,难道我们要写一万行代码么?(转载请指明出于breaksoftware的csdn博客) EXPECT_TRUE(IsPrime(0)); EXPECT_TRUE(IsPrime(1)); EXPECT_TRUE(IsPrime(2)); ...... EXPECT_TRUE(IsPrime(9999)); 这种写法明显是不合理的.GTest框架当然

Dubbo原理和源码解析之服务暴露

一.框架设计 在官方<Dubbo 用户指南>架构部分,给出了服务调用的整体架构和流程: 另外,在官方<Dubbo 开发指南>框架设计部分,给出了整体设计: 以及暴露服务时序图: 本文将根据以上几张图,分析服务暴露的实现原理,并进行详细的代码跟踪与解析. 二.原理和源码解析 2.1 标签解析 从文章<Dubbo原理和源码解析之标签解析>中我们知道,<dubbo:service> 标签会被解析成 ServiceBean. ServiceBean 实现了 Init

EventBus的使用和源码解析

一.基本介绍 EventBus 是一个 Android 事件发布/订阅框架,通过解耦发布者和订阅者简化 Android 事件传递,这里的事件可以理解为消息,本文中统一称为事件.事件传递既可用于 Android 四大组件间通讯,也可以用户异步线程和主线程间通讯等等.EventBus EventBus3.0版本有较大的更新,性能上有很大提升.这里主要介绍新版本. 传统的事件传递方式包括:Handler.BroadCastReceiver.Interface 回调,相比之下 EventBus 的优点是

Android 事件总线OTTO使用说明和源码解析

一.Otto简单介绍 OTTO是Square推出的库,地址:https://github.com/square/otto 先来看看otto的官方介绍 An enhanced Guava-based event bus with emphasis on Android support.Otto is an event bus designed to decouple different parts of your application while still allowing them to c

Android依赖注入Dagger的使用和源码解析(上篇)

一.基本概念 依赖注入(DI)和控制反转(IOC): 依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源:而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源. 使用依赖注入可以带来以下好处: 依赖的注入和配置独立于组件之外. 因为对象是在一个独立.不耦合的地方初始化,所以当注入抽象方法的时候,我们只需要修改对象的实现方法,而不用大改代码库. 依赖可以注入到一个组件中:我们可以注入这

设计模式课程 设计模式精讲 4-3 简单工厂源码解析

1 源码解析 1.1 Calendar源码解析 1.2 DriverManager源码解析 1 源码解析 1.1 Calendar源码解析 /** * Gets a calendar using the specified time zone and default locale. * The <code>Calendar</code> returned is based on the current time * in the given time zone with the d

Queue(队列)接口和其实现类PriorityQueue(优先级队列)源码解析

前面介绍的Stack是新进后出,而Queue是先进先出的 1.Queue结构 public interface Queue<E> extends Collection<E> { boolean add(E e); boolean offer(E e); E remove(); E poll(); E element(); E peek(); } Queue是一个接口. 2.PriorityQueue源码分析 PriorityQueue是一个优先队列,和先进先出的队列的区别是: 优先