运维开发笔记整理-基于类的视图(CBV)
运维开发笔记整理-基于类的视图(CBV)
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.FBV与CBV
1>.什么是FBV
FBC(function base views)就是在视图里使用函数处理请求。在之前django的学习中,我们一直使用的是这种方式,所以不在赘述。
2>.什么是CBV
CBV(class base views)就是在视图里使用类处理请求。
Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的有限就错失了(比如封装,继承和多态)。所以Django在后来加入来Class-Based-View。可以让我们用类写Vie。这样做的有点主要有下面两种:
第一:提高类代码的复用性,可以使用面向对象的技术,比如多继承。
第二:可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码的可读性。
二.使用class-based views
1>.编写login.html登录页面
<html lang="en" style="visibility: visible; display: block;">
<head>
<meta charset="utf-8">
<title>登录 - 北京硬核聚视科技有限公司运维平台</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/png" href="/static/cms/img/logo/影视大全@25x25px.png">
<link type="text/css" rel="stylesheet" property="stylesheet" href="/static/cms/css/bootstrap3.css">
</head>
<body class="Fill">
<nav class="navbar navbar-default">
<div class="navbar-inner">
<div class="navbar-header">
<a class="navbar-brand brand" data-event-category="Top Nav Menu" data-event="Product Logo"
href="https://www.cnblogs.com/yinzhengjie/" title="北京硬核聚视科技有限公司: 主页"><img
src="/static/cms/img/logo/AGGRX.png"></a>
<span class="hidden productName">北京硬核聚视科技有限公司</span>
</div> <!-- Be sure to leave the brand out there if you want it shown -->
<ul class="nav navbar-nav pull-right">
<li role="presentation">
<a>加入我们</a></li>
<li role="presentation">
<a>帮助</a></li>
</ul> </div>
</nav> <div class="" id="main-page-content">
<!--[if lte IE 8]>
<style scoped="scoped">
.WarningOldIE{
margin: 10px;
background: #ecc;
color: #611;
border: 2px solid;
padding: 10px;
font-family: sans-serif;
font-size: 14px;
}
</style> <div class="WarningOldIE">
<p>您使用的浏览器不受支持。</p>
<p>北京硬核聚视科技有限公司 在 <a href="http://www.google.com/chrome/">Google Chrome</a>、<a href="http://www.apple.com/safari/">Apple Safari</a>、<a href="http://getfirefox.com/">Mozilla Firefox</a> 或 <a href="http://www.microsoft.com/windows/internet-explorer/">Microsoft Internet Explorer 9 及更高版本中可获得最佳体验。</a></p>
</div>
<![endif]-->
<style>
html {
display: none;
visibility: hidden;
}
</style> <link type="text/css" rel="stylesheet" property="stylesheet" href="/static/cms/css/LoginForm.css?v=5.15.1"> <div class="LoginContainer">
<h1 class="hidden">登录</h1>
<!--[if lte IE 8]>
<style scoped="scoped">
.cui-login-form {
display: none;
}
.license-message {
display: none;
}
</style>
<![endif]-->
<form class="cui-login-form" action="#" method="POST" >
<div class="session-expired hidden">
<h1>由于不活动而自动注销</h1>
<p class="bold">您现在已注销帐户。</p>
<p>您大约有 30 分钟 没有任何活动,为了您的安全,北京硬核聚视科技有限公司 自动注销了您的帐户。请在下面重新登录以继续操作。
</p></div> <div class="control-group ">
<input type="text" placeholder="用户名" name="yzj_username">
<input type="password" placeholder="密码" name="yzj_password">
<input type="hidden" name="returnUrl" value="">
<div title="选中此复选框将使您在两周内或明确注销之前保持登录状态。" class="checkbox"><label><input type="checkbox"
name="_spring_security_remember_me">保留我的信息</label>
</div>
<button type="submit" class="btn btn-primary" name="submit">登录</button>
</div>
</form><!-- .cui-login-form -->
</div><!-- LoginContainer -->
</div> </body>
</html>
2>.编写视图函数
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ from django.http import HttpResponse
from django.shortcuts import render
from django.views import View class LoginView(View): def get(self,request):
return render(request,"login.html") def post(self,request):
print("调用了POST方法!")
return HttpResponse("post...")
3>.编写url函数
#!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ from django.conf.urls import url
from . import views urlpatterns = [
url(r"^login/",views.LoginView.as_view()),
]
Django的url是将一个请求分配给可调用的函数的,而不是一个class。针对这个问题,class-based view提供了一个as_view()
静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()
方法,dispatch()
方法会根据request的method的不同调用相应的方法来处理request(如get()
, post()
等)。到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。
我们随意输入一些字符串,会发送post请求,如下:
三.View源码分析
基于类的视图:
视图是一个可调用的对象,它接收一个请求然后返回一个响应,这个可调用对象可以不只 是函数,Django提供一些可以用作视图的类。
基于类的视图使用Python 对象实现视图,它提供除函数视图之外的另外一种方式。
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)]
四.使用Mixin
下图引用自:https://www.cnblogs.com/yuanchenqi/articles/8715364.html。
我觉得要理解django的class-based-view(以下简称cbv),首先要明白django引入cbv的目的是什么。在django1.3之前,generic view也就是所谓的通用视图,使用的是function-based-view(fbv),亦即基于函数的视图。有人认为fbv比cbv更pythonic,窃以为不然。python的一大重要的特性就是面向对象。而cbv更能体现python的面向对象。cbv是通过class的方式来实现视图方法的。class相对于function,更能利用多态的特定,因此更容易从宏观层面上将项目内的比较通用的功能抽象出来。关于多态,不多解释,有兴趣的同学自己Google。总之可以理解为一个东西具有多种形态(的特性)。cbv的实现原理通过看django的源码就很容易明白,大体就是由url路由到这个cbv之后,通过cbv内部的dispatch方法进行分发,将get请求分发给cbv.get方法处理,将post请求分发给cbv.post方法处理,其他方法类似。怎么利用多态呢?cbv里引入了mixin的概念。Mixin就是写好了的一些基础类,然后通过不同的Mixin组合成为最终想要的类。 所以,理解cbv的基础是,理解Mixin。Django中使用Mixin来重用代码,一个View Class可以继承多个Mixin,但是只能继承一个View(包括View的子类),推荐把View写在最右边,多个Mixin写在左边。
五.类视图登陆验证
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator class FooView(View):
@method_decorator(login_required)
def get(request, *args, **kwargs):
return HttpResponse("hello world")
运维开发笔记整理-基于类的视图(CBV)的更多相关文章
- 运维开发笔记整理-Django模型语法
运维开发笔记整理-Django模型语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.模型基本概念 1>.什么是模型 模型是你的数据唯一的,权威的信息源.它包含你所存储数 ...
- 运维开发笔记整理-URL配置
运维开发笔记整理-URL配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.URL路由 对于高质量的Web应用来说,使用简洁,优雅的URL的路由是一个非常值得重视的细节.Dja ...
- 运维开发笔记整理-QueryDict对象
运维开发笔记整理-QueryDict对象 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 客户端发送数据请求有很多种,相信运维人员已经很清楚了,如果不太清楚的话可以参考我之前的学习笔 ...
- 运维开发笔记整理-Request对象与Response对象
运维开发笔记整理-Request对象与HttpResponse对象 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.request对象 1>.什么是request 首先,我 ...
- 运维开发笔记整理-django日志配置
运维开发笔记整理-django日志配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Django日志 Django使用python内建的logging模块打印日志,Pytho ...
- 运维开发笔记整理-创建django用户
运维开发笔记整理-创建django用户 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.创建普通用户 C:\Users\yinzhengjie\softwares\Pycharm ...
- 运维开发笔记整理-template的使用
运维开发笔记整理-Django的template的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在上一篇博客中我们学习了HttpResponse 和JsonResponse方 ...
- 运维开发笔记整理-JsonResponse对象
运维开发笔记整理-JsonResponse对象 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.使用HttpResponse发送json格式的数据 1>.HttpRespo ...
- 运维开发笔记整理-使用Django编写helloworld
运维开发笔记整理-使用Django编写helloworld 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.创建Django项目 1>.创建Django项目 djang ...
随机推荐
- Qt开发经验小技巧21-30
如果出现Z-order assignment: is not a valid widget.错误提示,用记事本打开对应的ui文件,找到为空的地方,删除即可. 善于利用QComboBox的addItem ...
- k8s添加凭证
请参照:https://www.cnblogs.com/effortsing/p/10013441.html
- 容器版jenkins使用宿主机的kubectl命令
参照里面的第4步: https://www.cnblogs.com/effortsing/p/10486960.html
- copyProperties 忽略null值字段
在做项目时遇到需要copy两个对象之间的属性值,但是有源对象有null值,在使用BeanUtils来copy时null值会覆盖目标对象的同名字段属性值,然后采用以下方法找到null值字段,然后忽略: ...
- Kubernetes StatefulSet
StatefulSet 简介 在Kubernetes中,Pod的管理对象RC.Deployment.DaemonSet和Job都是面向无状态的服务.但现实中有很多服务是有状态的,特别是一些复杂的中间件 ...
- CentOS的vsftp修改默认配置路径方法
修改ftp的根目录只要修改/etc/vsftpd/vsftpd.conf文件即可: 加入如下几行: local_root=/var/www/htmlchroot_local_user=YESanon_ ...
- HDU6608-Fansblog(Miller_Rabbin素数判定,威尔逊定理应用,乘法逆元)
Problem Description Farmer John keeps a website called ‘FansBlog’ .Everyday , there are many people ...
- [转帖]在 k8s 中自动为域名配置 https
在 k8s 中自动为域名配置 https https://juejin.im/post/5db8d94be51d4529f73e2833 随着 web 的发展,https 对于现代网站来说是必不可少的 ...
- Python简介及开发环境搭建
Python简介 Python是一门动态解释性的强类型定义的计算机程序设计语言,是一种完全面向对象的语言,由荷兰人"龟叔"-Guido van Rossum于1989年开发,于19 ...
- Linux 进程间通信(管道、共享内存、消息队列、信号量)
进程通信 : 不同进程之间传播或交换信息 为什么要进程通信呢? 协同运行,项目模块化 通信原理 : 给多个进程提供一个都能访问到的缓冲区. 根据使用场景,我们能划分为以下几种通信 ...