使用

关于FBV和CBV的使用在之前有提到,点击穿越

准备

首先在视图中创建一个类并继承 django.views.View 类,在类中可定义各种请求方式对应执行的函数(函数名为请求方式名称小写)。

 from django.views import View

 class TestView(View):
def get(self, request):
return HttpResponse('get') def post(self, request):
return HttpResponse('post')

配置路由。

 from django.conf.urls import url
from app import views
urlpatterns = [
url(r'^test/', views.TestView.as_view()),
]

源码

做好上述准备之后,就可以通过相应的请求方法请求对应路由地址来执行CBV视图中对应请求方法名的函数,为什么Django能帮我们做到这一点呢?我们知道,在使用FBV时,路由地址对应的是一个函数句柄,而在CBV中,路由地址对应的是视图类的 as_view 函数的执行结果。例如:

 from django.conf.urls import url
from app import views def test():
pass urlpatterns = [
url(r'^test_FBV/', test),
url(r'^test_CBV/', views.TestView.as_view()),
]

所以从这里就可以看出, as_view 函数的返回值一定也是一个函数句柄。查看as_view()函数源码:

 class View(object):

     @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

直接看 29 行, as_view 函数的返回值其实就是 15 行定义的 view 函数。也就是说当请求对应地址时,实际上执行的是这个 view 函数,

从 17 、 18 行可以看出,当我们在视图类中定义了 get 函数而没有定义 head 函数时,就定义一个 head 函数指向了 get 函数。也就是说当只定义了 get 函数而以 head 方式请求时,会执行 get 函数。

再看 22 行, view 函数的返回值其实是 dispatch 函数的执行结果,看源码:

 class View(object):
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
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)

我们会发现,dispatch方法很简单,就是判断当前请求方法名称是否包含在 http_method_names 这个列表中。如果包含,则通过 getattr 从当前视图类实例中获取该方法名称函数句柄赋值给 handler ,最后执行。也就是说如果请求方式为 put ,就会调用视图类中的 put 函数;如果请求方式为 patch ,就会调用视图类中的 patch 函数。

Django中CBV源码解析的更多相关文章

  1. django中CBV源码分析

    前言:Django的视图处理方式有两种: FBV(function base views) 是在视图里基于函数形式处理请求. CBV(class base views)是在视图里基于类的形式处理请求. ...

  2. Django之CBV源码解析

    l链接跳转:https://www.cnblogs.com/hnlmy/p/9662798.html 以及https://www.cnblogs.com/hnlmy/p/10603999.html

  3. Django生命周期 URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析

    一.一个请求来到Django 的生命周期   FBV 不讨论 CBV: 请求被代理转发到uwsgi: 开始Django的流程: 首先经过中间件process_request (session等) 然后 ...

  4. django之admin源码解析

    解析admin的源码 第一步:项目启动,加载settings文件中的 INSTALLED_APPS 里边有几个app就加载几个,按照注册顺序来执行. 第二步:其中加载的是admin.py,加载每一个a ...

  5. 2) 接口规范 原生django接口、单查群查 postman工具 CBV源码解析

    内容了解 """ .接口:什么是接口.restful接口规范 .CBV生命周期源码 - 基于restful规范下的CBV接口 .请求组件.解析组件.响应组件 .序列化组件 ...

  6. CBV源码解析

    1.CBV(class based view) 首先定义一个视图函数,用类的方式定义: 举例: class LoginView(View): def get(self,request): return ...

  7. sklearn中MLPClassifier源码解析

    神经网络 .fit() 首先传入类私用方法._fit() 确定hidden_layer_size是可迭代的 调用_validate_hyperparameters验证超参数是否合法 验证输入的x和y是 ...

  8. Django中CBV及其源码解释

    FBV(function base views) 就是在视图里使用函数处理请求. CBV(class base views) 就是在视图里使用类处理请求. Python是一个面向对象的编程语言,如果只 ...

  9. CBV源码与APIView源码解析

    一.CBV源码解析 在我们写cbv的时候在url中和fbv的区别就是是否调用了as_view()方法,所以关键入手点就是这个方法 @classonlymethod # 这是类的绑定方法,这个cls是我 ...

随机推荐

  1. zookeeper做集群后启动不了,大部分原因是防火墙未关闭

    zookeeper做单机版,可以正常启动:但是zookeeper做集群后启动不了,大部分原因是防火墙未关闭. centos的关闭防火墙方法比较独立. systemctl stop firewalld. ...

  2. 【Java基础】Java注解简单入门

    注解简单来说就是配置,是特别的配置,之前常用的配置文件,可以用注解替换.然后通过反射去获取注解的信息. 如何定义一个注解 你在IDE中新建一个注解定义,是这样的结构的: package com.nic ...

  3. [Java并发编程(五)] Java volatile 的实现原理

    [Java并发编程(五)] Java volatile 的实现原理 简介 在多线程并发编程中 synchronized 和 volatile 都扮演着重要的角色,volatile 是轻量级的 sync ...

  4. 把去世的亲友做成聊天机器人,就能让生者慰藉、死者安息吗? - 看了 寻梦历险记,我的回答是 :是的,他/她永远活在我们心里 www.iremember.com.cn

    AppU 如今的我们,之所以离不开手机和互联网,是因为它们确实可以带来信息和方便,让我们轻松记录并分享自己的生活体验,留下了充满回忆的各种文字.语音,各种图片.视频…… 但你有没有想过,当我们逝世时, ...

  5. winscp的root连接ubuntu“拒绝访问”的解决方法

    转载:https://www.cnblogs.com/weizhxa/p/10098640.html 解决: 1.修改ssh配置文件:sudo vim etc/ssh/sshd_config 在#Pe ...

  6. springboot-aop面向切面编程

    需求: 项目中需要记录用户操作信息,例如用户登陆系统后做了那些操作,需要有具体的日志记录. 解决办法: 1.编写操作记录日志业务类,在使用的方法中调用(一般记录方式). 2.使用面向切面方式记录日志, ...

  7. easyui的tree节点的获取和选中

    1.设置选中tree的节点 var node = $('#tt').tree('find', 1);//找到id为”tt“这个树的节点id为”1“的对象$('#tt').tree('select', ...

  8. SQL in、not in、exists和not exists的区别:

    来自:http://blog.sina.com.cn/s/blog_8a0c4f130100zaw2.html 先谈谈in和exists的区别: exists:存在,后面一般都是子查询,当子查询返回行 ...

  9. react build后直接从浏览器打开

    存在两个问题 一,资源文件路径 config/paths.js 这里原来的.pathname:'/', 改成.pathname:'./' function getServedPath(appPacka ...

  10. CSS设置浏览器滚动条样式

    /*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ ::-webkit-scrollbar { width: 5px; height: 110px; background-color: #F5 ...