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)
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类视图简单使用和源码解析的更多相关文章
- Appium自动化(11) - 详解 Applications 类里的方法和源码解析
如果你还想从头学起Appium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1693896.html 前言 Applications 类 ...
- rest-framework之视图和源码解析
视图和源码解析 通过使用mixin类编写视图: from rest_framework import mixins from rest_framework import generics class ...
- Dubbo原理和源码解析之服务引用
一.框架设计 在官方<Dubbo 开发指南>框架设计部分,给出了引用服务时序图: 另外,在官方<Dubbo 用户指南>集群容错部分,给出了服务引用的各功能组件关系图: 本文将根 ...
- Dubbo原理和源码解析之“微内核+插件”机制
github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...
- Spring源码解析02:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析
一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...
- Spring源码解析 | 第二篇:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析
一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...
- Go语言备忘录:net/http包的使用模式和源码解析
本文是晚辈对net/http包的一点浅显的理解,文中如有错误的地方请前辈们指出,以免误导! 转摘本文也请注明出处:Go语言备忘录:net/http包的使用模式和源码解析,多谢! 目录: 一.http ...
- Dubbo原理和源码解析之标签解析
一.Dubbo 配置方式 Dubbo 支持多种配置方式: XML 配置:基于 Spring 的 Schema 和 XML 扩展机制实现 属性配置:加载 classpath 根目录下的 dubbo.pr ...
- Go语言备忘录(3):net/http包的使用模式和源码解析
本文是晚辈对net/http包的一点浅显的理解,文中如有错误的地方请前辈们指出,以免误导! 转摘本文也请注明出处:Go语言备忘录(3):net/http包的使用模式和源码解析,多谢! 目录: 一.h ...
随机推荐
- html基础用法(下)
设计表格: <html> <head> <title>表格</title> <meta charset="utf-8" /&g ...
- Oracle 11g RAC小结
1.查看数据库所有实例与状态 unixdev$[/home/grid]srvctl status database -d unixdev Instance unixdev11 is running o ...
- 使用actionerror做失败登录验证
一. 登录页面中放置如下代码: <h4>员工登录</h4> <div style="color:red"> <s:actionerror/ ...
- CodePush自定义更新弹框及下载进度条
CodePush 热更新之自定义更新弹框及下载进度 先来几张弹框效果图 非强制更新场景 image 强制更新场景 image 更新包下载进度效果 image 核心代码 这里的热更新Modal框,是封装 ...
- Swift_字典详解
Swift_字典详解 点击查看源码 初始化 fileprivate func testInit() { //空字典 var dic = [String:String]() print(dic) dic ...
- Java的内存--存储(1)
有次去面试,面试官突然问我这个问题,当时我只知道怎么写最优化,但是具体不知道为什么那样写,身价立马下降哦 1. 以下开发习惯,你怎么看? for(int i=0;i<2;i++){ Person ...
- P1247 取火柴游戏
题目描述 输入k及k个整数n1,n2,-,nk,表示有k堆火柴棒,第i堆火柴棒的根数为ni:接着便是你和计算机取火柴棒的对弈游戏.取的规则如下:每次可以从一堆中取走若干根火柴,也可以一堆全部取走,但不 ...
- 【TOJ 5103】Electric Fence(皮克定理)
描述 In this problem, `lattice points' in the plane are points with integer coordinates. In order to c ...
- Layui上传文件以及数据表格
layui对于一些前端小白来说,例如我,真的非常的好用,不用去花很多很多的心思在前端美化中,并且提高了很大的工作效率.所以建议一些觉得自己前端技术不是很强,但是想让前端美化一点的可以使用layui. ...
- C#判断系统是64位还是32位 支持.net4.0以前的版本
C#判断系统是64位还是32位的时候引用了一串代码,这个代码是从园子里面其他博文中转载过来的,引入自己的项目中发现无法使用,在引用了相应的命名空间之后还是提示: "未能找到类型或命名空间名称 ...