django CBV 源码分析

FBV和CBV

FBV(function base views) 就是在视图里使用函数处理请求。 
在之前django的学习中,我们一直使用的是这种方式,所以不再赘述。

CBV(class base views) 就是在视图里使用类处理请求。 
Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:

提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承) 
可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

CBV 源码分析

class View(object):
"""
Intentionally simple parent class for all views. Only implements
dispatch-by-method and simple sanity checking.
""" http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] def __init__(self, **kwargs):
"""
Constructor. Called in the URLconf; can contain helpful extra
keyword arguments, and other things.
"""
# Go through keyword arguments, and either save their values to our
# instance, or raise an error.
for key, value in six.iteritems(kwargs):
setattr(self, key, value) @classonlymethod
def as_view(cls, **initkwargs):
"""
Main entry point for a request-response process.
"""
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 # take name and docstring from class
update_wrapper(view, cls, updated=()) # and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
return view def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
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) def http_method_not_allowed(self, request, *args, **kwargs):
logger.warning(
'Method Not Allowed (%s): %s', request.method, request.path,
extra={'status_code': 405, 'request': request}
)
return http.HttpResponseNotAllowed(self._allowed_methods()) def options(self, request, *args, **kwargs):
"""
Handles responding to requests for the OPTIONS HTTP verb.
"""
response = http.HttpResponse()
response['Allow'] = ', '.join(self._allowed_methods())
response['Content-Length'] = ''
return response def _allowed_methods(self):
return [m.upper() for m in self.http_method_names if hasattr(self, m)]

class View(object)

在url中会执行一个叫做as_view的方法,这个方法在加载url时候会执行   得到一个返回值view 是一个函数 供url调用

那么view 究竟做了什么呢?

当url执行view时候,会把下边这句代码作为返回值

self.dispatch(request, *args, **kwargs)

所view 会调用当前调用类的dispatch

CBV 的api接口 dispatch

在执行dispatch的时候,如果views中的视图类 自定义了dispatch那么将优先执行自定义的dispatch  由此可在请求处理前增加一些处理,

然后再用super方法去调用父类的dispatch ,当然也可以自己把父类的功能全部写在自己的自定义里边。

那么就说下父类的dispatch做了什么功能呢

简单的说-----分发

复杂的说-----找到这次请求对应的类型,然后用反射把这个方法取到,然后作为自己的返回值,返回给调用这个方法的view

因此我们得到一个结论,两种方式的最终结果都是把要执行的视图函数放在url的第二个参数位置  不过CBV在请求的前后给我们提供了丰富的扩展空间

CBV流程的更多相关文章

  1. CBV请求流程源码分析

    一.CBV流程解析 urls.py urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^book/', views.BookView.as ...

  2. flask中的CBV和FBV

    flask中CBV使用 from flask import Flask, views app = Flask(__name__) class Login(views.MethodView): meth ...

  3. rest_framework 认证流程

    一.基本流程 rest_framework框架是基于CBV基础开发的(VPIView(View)),所以基本流程与CBV流程相似 当我们的请求发来后,会走as_views,执行view里面的方法,最开 ...

  4. 分页组件与CBV

    一. 自定义分页 1.准备工作 (1).首先在models.py中创建一张book表用来存储数据 from django.db import models class Book(models.Mode ...

  5. Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)

    一.Django请求生命周期: 前端发出请求到后端,通过Django处理.响应返回给前端相关结果的过程 先进入实现了wsgi协议的web服务器--->进入django中间件--->路由f分 ...

  6. ORM some

    1 -- 增 models.表名(类).objects.create(字段1=值,字段2=值) 查 models.表名(类).objects.get(pk = 3) models.表名(类).obje ...

  7. day 94 RestFramework序列化组件与视图view

    一 .复习 1. CBV流程 class BookView(View): def get(): pass def post(): pass #url(r'^books/', views.BookVie ...

  8. restframework框架之认证

    1. 认证之APIView 在聊APIView之前, 我们先重温一下django2.x的CBV流程 a. 对于django而言, 当浏览器请求到达之后,按照规则首先会经过各大中间件(Middlewar ...

  9. Django 内容回顾

    模板 变量 {{ }} 标签 {% %} if elif else for empty forloop() with...as csrf_token 过滤器 default length add da ...

随机推荐

  1. GLEW扩展库【转】

    http://blog.sina.com.cn/s/blog_4aff14d50100ydsy.html 一.关于GLEW扩展库: GLEW是一个跨平台的C++扩展库,基于OpenGL图形接口.使用O ...

  2. Yahoo 股票数据抓取

    Yahoo提供日线级别的历史数据,包括国内外各交易所的数据,可以写爬虫抓取数据做简单的分析. api基本格式如下: http://ichart.yahoo.com/table.csv?s=<st ...

  3. 从C转到JAVA学习路之struct与class对比(转)

    转自:http://blog.csdn.net/andywxf01/article/details/53506549 JAVA里最牛B的最基本的就是类,而C语言中的struct也可以定义自己的数据结构 ...

  4. mssql性能优化

    总结下SQL SERVER数据库性能优化相关的注意事项,在网上搜索了一下,发现很多文章,有的都列出了上百条,但是仔细看发现,有很多似是而非或者过时(可能对SQL SERVER6.5以前的版本或者ORA ...

  5. PHP+MYSQL的搭建

    如今准备研究下微信的开发,所以要研究下PHP了,但对这个平台还是非常陌生的,所以网上找了些资料并測试,现贴出来给大家參考. 第一步:我们先下载[PHPStudy 2013]或者最新版本号: 下载地址: ...

  6. 窥探try ... catch与__try ... __except的区别

    VC中的这两个东西肯定谁都用过, 不过它们之间有什么区别, 正好有时间研究了一下, 如果有错误欢迎拍砖.基于VC2005, 32位XP 平台测试通过. 估计对于其他版本的VC和操作系统是不通用的. 1 ...

  7. sql DATEPART() MONTH() convert() cast() dateadd() DATEDIFF() with(nolock)

    DATEPART() 函数用于返回日期/时间的单独部分,比如年.月.日.小时.分钟等等. 语法 DATEPART(datepart,date) date 参数是合法的日期表达式.datepart 参数 ...

  8. Leetcode--easy系列3

    #26 Remove Duplicates from Sorted Array Given a sorted array, remove the duplicates in place such th ...

  9. http协议---简述

    http(Hypertext transfer protocol)超文本传输协议,通过浏览器和服务器进行数据交互,进行超文本(文本.图片.视频等)传输的规定. 也就是说,http协议规定了超文本传输所 ...

  10. 红茶一杯话Binder(传输机制篇_上)

    红茶一杯话Binder (传输机制篇_上) 侯 亮 1 Binder是如何做到精确打击的? 我们先问一个问题,binder机制到底是如何从代理对象找到其对应的binder实体呢?难道它有某种制导装置吗 ...