前言
如果不太清楚CBV和FBV的区别请点击这个:CBV和FBV的区别
可以打开项目复制代码,跟着每一步学习,想要快速了解他们之间的区别,可以直接跳到总结
一、CBV是什么?
CBV(Class-Based Views)是视图编写方式
二、使用步骤
1.实例代码引入
代码如下(示例):
views.py:
from django.shortcuts import render, HttpResponse
from django.views import View
class DateCBVViews(View):
def get(self,request,*args,**kwargs):
return HttpResponse("CBV_GET方法")
def post(self,request,*args,**kwargs):
return HttpResponse("CBV_POST方法")
urls.py:
from django.urls import path,re_path
from api import views
urlpatterns = [
path('api/cbv/',views.DateCBVViews.as_view()),]
api是我项目名称根据自己的项目去改
2.源码分析:
CTRL+鼠标左键点击urls.py中路由中的as_view()方法
下滑找到这个方法的最后,然后发现返回的是view方法,CTRL+鼠标左键点击view
点击后发现,调用的是as_view()方法中写的view方法,下滑找到dispatch方法
继续点击查看这个方法
重点来了,最重要的就是这几行代码
request.method.lower()就是把请求方式改成小写(例如get请求方式),request.method就是请求方式,lower()就是改成小写
http_method_names我们可以点击进去查看一下
getattr()
函数在Python中用于从对象中获取指定属性的值。它的语法是:
getattr(对象, 属性, 默认值)
对象
是要从中获取属性值的对象。属性
是要获取其值的属性的名称。默认值
(可选)是在属性不存在时要返回的值(如果不提供,则会引发 AttributeError)。
所以这里代码的意思就是if判读 request.method.lower() 请求的方法在 self.http_method_names:里面的话,就执行 getattr方法,self就是我们一开始定义的DateCBVViews类对象,所以这里的
handler =getattr( self, request.method.lower(), self.http_method_not_allowed )
的意思就是(注意:假设这里请求的是get方式):把DateCBVViews.get(注意:不存在就会执行self.http_method_not_allowed 方法)赋值给handler,最后通过
return handler(request, *args, **kwargs)
返回并且执行DateCBVViews.get方法
(注意:刚开始赋值给handler的时候并没有执行.get方法,是最后return handler(request, *args, **kwargs)相当于DateCBVViews.get+()加了个括号才算是执行的这个方法)
3.补充进阶:
了解这一些后我们可以重新写DateCBVViews这个类,添加一些自己的功能
class DateCBVViews(View):
def dispatch(self, request, *args, **kwargs):
print("hello world")
ret=super().dispatch(request, *args, **kwargs)
return ret
def get(self,request,*args,**kwargs):
return HttpResponse("CBV_GET方法")
def post(self,request,*args,**kwargs):
return HttpResponse("CBV_POST方法")
super()就是执行父类的dispatch方法,这里我们只是增加一些功能,不改变dispatch的根本方法,所以要执行父类的dispatch
比如:我这个就是无论请求的是那个方法都会先输出“hello world”,所以我们了解源码可以重写自己的方法,让项目实现更加简单
总结
以上就是今天要讲的内容,本文仅仅简单介绍了CBV的使用以及源码分析,总的来说执行流程就是
as_view ==> as_view.view ==> dispatch() ==>执行请求的方式(例如get)
我们了解源码后就可以自定义dispatch()方法,提供一些自己写的功能了