目录

CBV 和 FBV 介绍

  1. 路由绑定

    urlpatterns = [
    # 1)项目启动,将test函数地址绑定给/test/路由
    # 2)请求/test/访问后台,后台就会调用绑定的test函数
    url(r'^test/$', views.test), # 1)项目启动,将as_view()函数执行结果返回的view函数地址绑定给/test/路由
    # 2)请求/test/访问后台,后台就会调用绑定的view函数
    # 3)view函数会将请求交给dispatch方法完成分发,分发(反射)给视图类的不同方法处理请求
    url(r'^test/$', views.Test.as_view()),
    ]
  2. 业务处理

    • fbv 每一个接口都会对应一个函数来响应请求

    • cbv 可以将一个资源的增删改查所有操放在一个类中管理,在内部再分方法逐一处理

      (高内聚低耦合:六个接口和一个类有关,但都能在类内部处理)

三个View其实是同一个类
继承View的目的:
i)继承as_view()方法,完成路由的配置
ii)继承dispath()方法,完成请求分发
注:如果自己写as_view()和dispath()方法,自定义视图类可以不用继承任何类的
from django.http import JsonResponse
from django.views import View
from django.views.generic import View
from django.views.generic.base import View\
class Test(View):
def get(self, request, *args, **kwargs):
return JsonResponse('cbv ok', safe=False)

django 的类视图拥有自动查找指定方法的功能, 通过调用是通过as_view()方法实现

urls.py

from meduo_mall.demo import views

urlpatterns = [
url(r'register/$', views.Demo.as_view())
]

views.py

from django.views.generic import View

class Demo(View):

    def get(self, request):
return HttpResponse('get page') def post(self, request):
return HttpResponse('post page')

为什么as_view能自动匹配指定的方法

先看源码

    @classonlymethod
def as_view(cls, **initkwargs): # 实际上是一个闭包 返回 view函数
"""
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): # 作用:增加属性, 调用dispatch方法
self = cls(**initkwargs) # 创建一个 cls 的实例对象, cls 是调用这个方法的 类(Demo)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request # 为对象增加 request, args, kwargs 三个属性
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,
if request.method.lower() in self.http_method_names: # 判断请求的方法类视图是否拥有, http_method_names=['get', 'post']
handler = getattr(self, request.method.lower(), self.http_method_not_allowed) # 如果存在 取出该方法
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) # 执行该方法

简化版

    @classonlymethod
def as_view(cls, **initkwargs): # 实际上是一个闭包 返回 view函数
"""
Main entry point for a request-response process.
"""
def view(request, *args, **kwargs): # 作用:增加属性, 调用dispatch方法
self = cls(**initkwargs) # 创建一个 cls 的实例对象, cls 是调用这个方法的 类(Demo)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request # 为对象增加 request, args, kwargs 三个属性
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs) # 找到指定的请求方法, 并调用它 return view def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
if request.method.lower() in self.http_method_names: # 判断请求的方法类视图是否拥有, http_method_names=['get', 'post']
handler = getattr(self, request.method.lower(), self.http_method_not_allowed) # 如果存在 取出该方法
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) # 返回该请求方法执行的结果

再简化

def as_view(): # 校验 + 返回view方法
# 一些校验
...
def view(): # 执行视图
# 增加 为对象request, args, kwargs 属性
...
return dispatch() # 调用指定的请求方法
return view def dispatch(): # 真正的查找指定的方法, 并调用该方法
...
return handler()

调用顺序: as_view --> view --> dispatch

  • 可以看出as_view实际上是一个闭包, 它的作用做一些校验工作, 再返回view方法.
  • 而view方法的作用是给请求对象补充三个参数, 并调用 dispatch方法处理
  • dispatch方法查找到指定的请求方法, 并执行

可以得出结论: 实际上真正实现查找的方法是 dispatch方法

高内聚低耦合、生命周期 as_view() => dispatch() => 视图类响应方法

FBV CBV的更多相关文章

  1. Django FBV/CBV、中间件、GIT使用

    s5day82 内容回顾: 1. Http请求本质 Django程序:socket服务端 a. 服务端监听IP和端口 c. 接受请求 \r\n\r\n:请求头和请求体 \r\n & reque ...

  2. 回顾基础知识,类,fbv,cbv

    一 类中绑定方法的传参,不需要self class Foo(object): def __init__(self,name): self.name = name def foo(self,x): se ...

  3. Django 路由视图FBV/CBV

    路由层  url路由层结构 from django.conf.urls import url from django.contrib import admin from app01 import vi ...

  4. Django FBV CBV以及使用django提供的API接口

    FBV 和 CBV 使用哪一种方式都可以,根据自己的情况进行选择 看看FBV的代码 URL的写法: from django.conf.urls import url from api import v ...

  5. django FBV +CBV 视图处理方式总结

    1.FBV(function base views) 在视图里使用函数处理请求. url:        re_path('fbv', views.fbv),        # url(r'^fbv' ...

  6. $Django 虚拟环境,2.0、1.0路由层区别,Httprequest对象,视图层(fbv,cbv),文件上传

    1 虚拟环境:解决问题同一台机器上可以运行不同版本的django,  1 用pychanrm创建--->files-->newproject--->选择虚拟环境  2 setting ...

  7. Django之FBV&CBV

    CBV与FBV是django视图中处理请求的两种方式 FBV FBV也就是function base views,字面意思函数基础视图,使用函数的方式处理请求url分发中添加的参数为视图处理函数名, ...

  8. 巨蟒python全栈开发django6: FBV&CBV&&单表查询的其他方法

    练习CBV用法 截图中的action="/cbv/",应该是这样 上边红图,说明mysql有问题,需要重启一下 返回,输入的内容 @wrapper==>cbv=wrapper ...

  9. Django---view视图FBV&CBV

    一:创建项目和应用: 或者用命令创建: 1:django-admin.py startproject CBV&FBV 2: cd CBV&FBV (路径切到该文件夹下) 3: pyth ...

  10. [oldboy-django][2深入django]FBV + CBV + 装饰器

    FBV django CBV & FBV - FBV function basic view a. urls 设置 urls(r'^test.html$', views.test) b. vi ...

随机推荐

  1. spring boot整合Thymeleaf

    1.引入thymeleaf: <dependency> <groupId>org.springframework.boot</groupId> <artifa ...

  2. OpenCV学习 - 图片集合成视频

    这个很简单,没什么好说的...这里给出学习手册: 1.官方教程:https://docs.opencv.org 2.这个是一些video相关的API参考:https://docs.opencv.org ...

  3. 解决误删libc.so.6过程的参考资料

    说说前因后果:因为之前安装了filezilla,发现安装不了,说是libc.so.6老旧了.差不多过了一个星期,也就是前天升级gcc成功后决定再解决这个问题.gcc升级成功后,决定创建新链接...然后 ...

  4. adblock广告过滤

    1.在 img的 src中 出现 ad连在一起的情况,会被adblock过滤掉. 例如 <img id="adasdd" class="ad_mina" ...

  5. git分支在项目中管理

    实际项目中如何使用Git做分支管理 2018年06月24日 18:08:24 ShuSheng007 阅读数:9241   版权声明: https://blog.csdn.net/ShuSheng00 ...

  6. 「ZJOI2011」最小割

    「ZJOI2011」最小割 传送门 建出最小割树,然后暴力计算任意两点之间最小割即可. 多组数据记得初始化. 参考代码: #include <algorithm> #include < ...

  7. 泛型和Object的区别?

    泛型声明 public <T> T doSomeThing(T t){ return t; } Object声明 public Object doSomeThing(Object obj) ...

  8. [转]Mysql连表之多对多

    转自 回到顶部 连表多对多 可以理解成一夫多妻和一妻多夫. 男人表: nid name 1 xxx 2 yyy 3 zzz 女人表: nid name 1 aaa 2 bbb 3 ccc 要让两个表建 ...

  9. Go的WaitGroup

    goroutine使用方便,但是如果不加以处理一般会deadlock,因为goroutine配合Chanel的话只能是一进一出,否则就会卡在那里.下面一个示例就是利用这个WaitGroup处理这种死锁 ...

  10. 03.Scala编程实战

    Scala编程实战 1.    课程目标 1.1.  目标:使用Akka实现一个简易版的spark通信框架 2.    项目概述 2.1.   需求 Hivesql----------> sel ...