目录

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. Codeforces Round #600 (Div. 2) - B. Silly Mistake(模拟)

    题意:有一个公司,每天有员工进出,$a[i]>0$时表示$a[i]$这个员工进入公司,$a[i]<0$时表示$-a[i]$这个员工出公司,公司对进出办公室有一些严格的规定 员工每天最多只能 ...

  2. VUE 鼠标右键自定义

    需要在区域内右击自定义菜单的DIV绑定contextmenu右击事件 <div   style="width:100% ; z-index: inherit;position: rel ...

  3. 最全BT磁力搜索引擎,国外最受欢迎的BT-磁力网站(整理分享,每日不断更新...)

    最全BT磁力搜索引擎索引(整理分享,每日更新) 1.海盗湾 The Pirate Bay 2.磁力天堂(BT磁力搜索下载-磁力天堂) www.btaa.xyz  (资源多,下载速度可以,建议用手机访问 ...

  4. linux文件或目录属性

    wc(word count)命令的功能:统计指定文件的字节数.字数.行数.,并将统计结果显示输出 命令参数: -c 只显示字节数 -l    只显示行数 -w 只显示字数 od命令:查看二进制文件信息 ...

  5. github日常的基本命令

    git 常用命令 git clone 仓库地址 -从远端克隆项目 git pull -从远端拉取代码 git pull -p -从远端拉取代码和分支 提交代码流程: git add xxx -添加到暂 ...

  6. [转]利用 Commons-Fileupload 实现文件上传

    转载 Java Web开发人员可以使用Apache文件上传组件来接收浏览器上传的文件,该组件由多个类共同组成,但是,对于使用该组件来编写文件上传功能的Java Web开发人员来说,只需要了解和使用其中 ...

  7. Docker示例命令

    1.docker run -t -i -v /root/workspace/node:/home/exam:rw docker.io/node bin/sh    -t 给容器挂载一个伪终端    - ...

  8. 吴裕雄--天生自然PythonDjangoWeb企业开发:解决Pythonno module named "XX"问题

    在项目中加入 sys.path.append('你的django项目路径') sys.path.append('python的site-packages路径')

  9. 墨西哥萨卡特卡斯将举行GNOME GUADEC 2020 峰会

    导读 GNOME基金会今天宣布了下两届GUADEC(GNOME用户和开发人员欧洲会议)活动的主办城市,这也将是GNOME桌面环境下一版本的代号. 随着GNOME 3.34 “Thessalonik”的 ...

  10. java#临时文件目录

    String tmpDir=System.getProperty("java.io.tmpdir");