Django之FBV与CBV
一、FBV与CBV
FBV(function based views),即基于函数的视图;CBV(class based views),即基于类的视图,也是基于对象的视图。当看到这个解释时,我是很萌的,我仔细回想了一下,哪里有基于类的视图啊,怎么我之前写的视图都是一个一个的函数啊,奇怪了,很多人都应该和我一样蒙(大佬除外哈)。没错我之前写的所有的视图都是基于函数的,所以今天咋们不去扯什么是FBV了,实在不知道的,可以看看在今天之前的所有视图,绝对都是FBV模型的(这个我敢打包票)。
二、CBV的实现代码
当听到基于class时,就会想到对象,瞬间有点慌,总感觉对象这个东西要比函数难,没有那么好理解,这应该是大多数人的共性,但在python中处处皆对象,你不想碰他就不能碰他?????不可能的,要想使你的代码更有水平,那你就避不开对象,而且对于开发来说,肯定都是要用到对象。其实哈这个基于对象的视图很好理解。
1,先写视图
from django.shortcuts import render,HttpResponse
from django.views import View
class myview(View):
def get(self,request):
return render(request,'login.html')
def post(self,request):
return HttpResponse('post请求')
2,写一个登录的页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<label for="user">用户名:</label>
<input type="text" name="user" id="user">
<label for="pwd">密码:</label>
<input type="password" name="pwd" id="pwd">
<input type="submit" value="提交">
</form>
</body>
</html>
3,url
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.myview.as_view()),
]
4,分析过程
首先我们得看url,当请求路径是login时,会调用views里面的myview类的一个方法as_view,在这里我们先不管这个方法到底干了啥,只是说说执行流程。在浏览器地址栏输入login路径时,用的是get请求,它就会去调用myview类下的自己写的get,然后饭后一个登录页面;得到页面后输入用户名和密码之后点击提交按钮,又往login路径发送了一个post请求,这时就会调用myview类下的自己写的post方法,返回一个‘post请求’字符,这就是整个过程,从两个流程来看,大概可以猜出,整个过程中,django会判断请求的方式,不同的请求方式调用相应的方法
三、分析源码
既然在我自定义的myview类里没有写任何关于请求方式的逻辑,那我们应该猜测到,在myview继承的View类里面肯定有相关的东西(大佬经验,阅读源码时,看不懂就不要去看,不要去分析,只看我们需要的)。
1,源码
class View:
"""
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 kwargs.items():
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 HttpResponseNotAllowed(self._allowed_methods()) def options(self, request, *args, **kwargs):
"""Handle responding to requests for the OPTIONS HTTP verb."""
response = 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)]
2,剖析
在url里面,我们可以看到当请求过来后,执行的是views.myview.as_view(),所以我们去看看as_view()这个方法到底干了啥,首先在我们自定义的myview类里面没有这个方法,那就去父类View里找。
上面说过看不懂的就不要看,所以我把看不懂的给删除了
@classonlymethod
def as_view(cls, **initkwargs): #这是as_view方法 def view(request, *args, **kwargs): #这是as_view方法里嵌套一个方法view
self = cls(**initkwargs) #这是用myview类实例化的一个对象self
return self.dispatch(request, *args, **kwargs) #这是用实例化对象self去调用dispatch方法,然后作为view方法的返回值值
return view #这是返回view这个方法,也就是把view方法的返回值作为as_view的返回值,
接下来我们得去看看dispatch方法干了什么,首先也得从自定义的myview类里找dispatch方法,没找到,然后去父类View里找,
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
def dispatch(self, request, *args, **kwargs): #这是dispatch方法
if request.method.lower() in self.http_method_names: #这是把请求的方法取出来,然后小写,看有没有在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) #返回请求方式对应方法的执行结果
比如说是get请求进来后,它就利用反射会去myview里面拿到一个叫get的方法,在我的myview类下就有我自定义的get方法,然后执行它,得到一个HTTPResponse对象,返回给dispatch方法,dispatch方法又把这个HTTPResponse对选哪个返回给了view方法,
view方法又把这个对象返回给as_view方法,as_view方法又把这个作为响应返回给客户端,这整个过程简化中间的过程就会变成,get方法返回一个HTTPResponse对象给客户端
Django之FBV与CBV的更多相关文章
- django的FBV和CBV
title: python djano CBV FBV tags: python, djano, CBV, FBV grammar_cjkRuby: true --- python django的fu ...
- django的FBV和CBV的装饰器例子
备忘 def auth(func): def inner(request,*args,**kwargs): u = request.COOKIES.get('username111') if not ...
- Django之FBV和CBV的用法
FBV FBV,即 func base views,函数视图,在视图里使用函数处理请求. 以用户注册代码为例, 使用两个函数完成注册 初级注册代码 def register(request): &qu ...
- Django的FBV和CB
Django的FBV和CBV FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以不再赘述. CBV C ...
- django请求生命周期,FBV和CBV,ORM拾遗,Git
一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...
- django——FBV与CBV
引言 FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以不再赘述. CBV CBV(class bas ...
- python 全栈开发,Day84(django请求生命周期,FBV和CBV,ORM拾遗,Git)
一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...
- django基础 -- 4. 模板语言 过滤器 模板继承 FBV 和CBV 装饰器 组件
一.语法 两种特殊符号(语法): {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 二.变量 1. 可直接用 {{ 变量名 }} (可调用字符串, 数字 ,列表,字典,对象等) ...
- django中的FBV和CBV
django中请求处理方式有2种:FBV 和 CBV 一.FBV FBV(function base views) 就是在视图里使用函数处理请求. 看代码: urls.py from django.c ...
随机推荐
- 项目部署到服务器上之后request.getRemoteAddr()为什么获取的都是本地地址
获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了.如 ...
- Re:uxul
Re: Unbelieveable eXperience of University Life
- SWPU-ACM集训队周赛之组队赛(3-11) C题题解
点这里去看题 模拟,注意细节 #include<stdio.h> #include<string.h> int main() { ]; //q[]储存正负信息 scanf(&q ...
- 安装Intellij IDEA(ideaIU-2017.2.3)并完成Intellij IDEA的简单配置
一.Intellij IDEA的简介 Intellij IDEA是java语言的集成开发环境,与Eclipse相比,它的功能更多.更强大.更智能,Eclipse更适合刚学习java语言的初学者,它操作 ...
- 关于esp32的系统初始化启动过程及设计学习方法
对于esp32,其开发程序中有且只能有一个app_main函数,该函数是用户程序的入口,这在没有调用FreeRTOS的系统中相当于函数main,但其实在app_main之前,系统还有一段初始化的过程, ...
- FPGA的发展史及FPGA 的基础架构
通过了解早期FPGA的发展,理解FPGA究竟是干什么的,FPGA到底在电子设计领域起到了什么样的作用,下面是一张早期的设计过程 早期的设计流程过程中,只有当硬件完成了才能够得到功能的验证,随着集成电路 ...
- Dynamic Programming | Set 2 (Optimal Substructure Property)
正如我们在 Dynamic Programming | Set 1 (Overlapping Subproblems Property) 中讨论的那样,当一个问题具有以下2种性质时,建议使用动态规划来 ...
- 学习在dos下使用gcc来编译
这两年里,断断续续的学习和使用c,平时都是在CodeBlocks里写代码,编译程序,点一下按钮就行了.对整个编译过程是一点儿都不了解.相比当年学习java,真的是选择了两个不同的路,当年学习java的 ...
- jenkins+donet core持续集成环境搭建
一.Jenins+GitHub 参考 另外需要配置Global Tool Configuration 如果没有安装git,需下载安装,下载地址 二.jenkins发布donet core应用 1.配置 ...
- 压测工具之JMeter之环境配置及运行
一.下载JMeter 地址:http://jmeter.apache.org/download_jmeter.cgi 系统:win7 x64 在 Binaries 目录下选择一个合适自己系统的版本,不 ...