运维开发笔记整理-基于类的视图(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登录页面

  1. <html lang="en" style="visibility: visible; display: block;">
  2. <head>
  3. <meta charset="utf-8">
  4. <title>登录 - 北京硬核聚视科技有限公司运维平台</title>
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <link rel="shortcut icon" type="image/png" href="/static/cms/img/logo/影视大全@25x25px.png">
  7. <link type="text/css" rel="stylesheet" property="stylesheet" href="/static/cms/css/bootstrap3.css">
  8. </head>
  9. <body class="Fill">
  10. <nav class="navbar navbar-default">
  11. <div class="navbar-inner">
  12. <div class="navbar-header">
  13. <a class="navbar-brand brand" data-event-category="Top Nav Menu" data-event="Product Logo"
  14. href="https://www.cnblogs.com/yinzhengjie/" title="北京硬核聚视科技有限公司: 主页"><img
  15. src="/static/cms/img/logo/AGGRX.png"></a>
  16. <span class="hidden productName">北京硬核聚视科技有限公司</span>
  17. </div>
  18.  
  19. <!-- Be sure to leave the brand out there if you want it shown -->
  20. <ul class="nav navbar-nav pull-right">
  21. <li role="presentation">
  22. <a>加入我们</a></li>
  23. <li role="presentation">
  24. <a>帮助</a></li>
  25. </ul>
  26.  
  27. </div>
  28. </nav>
  29.  
  30. <div class="" id="main-page-content">
  31. <!--[if lte IE 8]>
  32. <style scoped="scoped">
  33. .WarningOldIE{
  34. margin: 10px;
  35. background: #ecc;
  36. color: #611;
  37. border: 2px solid;
  38. padding: 10px;
  39. font-family: sans-serif;
  40. font-size: 14px;
  41. }
  42. </style>
  43.  
  44. <div class="WarningOldIE">
  45. <p>您使用的浏览器不受支持。</p>
  46. <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>
  47. </div>
  48. <![endif]-->
  49. <style>
  50. html {
  51. display: none;
  52. visibility: hidden;
  53. }
  54. </style>
  55.  
  56. <link type="text/css" rel="stylesheet" property="stylesheet" href="/static/cms/css/LoginForm.css?v=5.15.1">
  57.  
  58. <div class="LoginContainer">
  59. <h1 class="hidden">登录</h1>
  60. <!--[if lte IE 8]>
  61. <style scoped="scoped">
  62. .cui-login-form {
  63. display: none;
  64. }
  65. .license-message {
  66. display: none;
  67. }
  68. </style>
  69. <![endif]-->
  70. <form class="cui-login-form" action="#" method="POST" >
  71. <div class="session-expired hidden">
  72. <h1>由于不活动而自动注销</h1>
  73. <p class="bold">您现在已注销帐户。</p>
  74. <p>您大约有 30 分钟 没有任何活动,为了您的安全,北京硬核聚视科技有限公司 自动注销了您的帐户。请在下面重新登录以继续操作。
  75. </p></div>
  76.  
  77. <div class="control-group ">
  78. <input type="text" placeholder="用户名" name="yzj_username">
  79. <input type="password" placeholder="密码" name="yzj_password">
  80. <input type="hidden" name="returnUrl" value="">
  81. <div title="选中此复选框将使您在两周内或明确注销之前保持登录状态。" class="checkbox"><label><input type="checkbox"
  82. name="_spring_security_remember_me">保留我的信息</label>
  83. </div>
  84. <button type="submit" class="btn btn-primary" name="submit">登录</button>
  85. </div>
  86. </form><!-- .cui-login-form -->
  87. </div><!-- LoginContainer -->
  88. </div>
  89.  
  90. </body>
  91. </html>

2>.编写视图函数

  1. #!/usr/bin/env python
  2. #_*_conding:utf-8_*_
  3. #@author :yinzhengjie
  4. #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/
  5.  
  6. from django.http import HttpResponse
  7. from django.shortcuts import render
  8. from django.views import View
  9.  
  10. class LoginView(View):
  11.  
  12. def get(self,request):
  13. return render(request,"login.html")
  14.  
  15. def post(self,request):
  16. print("调用了POST方法!")
  17. return HttpResponse("post...")

3>.编写url函数

  1. #!/usr/bin/env python
  2. #_*_conding:utf-8_*_
  3. #@author :yinzhengjie
  4. #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/
  5.  
  6. from django.conf.urls import url
  7. from . import views
  8.  
  9. urlpatterns = [
  10. url(r"^login/",views.LoginView.as_view()),
  11. ]

  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 对象实现视图,它提供除函数视图之外的另外一种方式。

  1. class View(object):
  2. """
  3. Intentionally simple parent class for all views. Only implements
  4. dispatch-by-method and simple sanity checking.
  5. """
  6.  
  7. http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
  8.  
  9. def __init__(self, **kwargs):
  10. """
  11. Constructor. Called in the URLconf; can contain helpful extra
  12. keyword arguments, and other things.
  13. """
  14. # Go through keyword arguments, and either save their values to our
  15. # instance, or raise an error.
  16. for key, value in six.iteritems(kwargs):
  17. setattr(self, key, value)
  18.  
  19. @classonlymethod
  20. def as_view(cls, **initkwargs):
  21. """
  22. Main entry point for a request-response process.
  23. """
  24. for key in initkwargs:
  25. if key in cls.http_method_names:
  26. raise TypeError("You tried to pass in the %s method name as a "
  27. "keyword argument to %s(). Don't do that."
  28. % (key, cls.__name__))
  29. if not hasattr(cls, key):
  30. raise TypeError("%s() received an invalid keyword %r. as_view "
  31. "only accepts arguments that are already "
  32. "attributes of the class." % (cls.__name__, key))
  33.  
  34. def view(request, *args, **kwargs):
  35. self = cls(**initkwargs)
  36. if hasattr(self, 'get') and not hasattr(self, 'head'):
  37. self.head = self.get
  38. self.request = request
  39. self.args = args
  40. self.kwargs = kwargs
  41. return self.dispatch(request, *args, **kwargs)
  42. view.view_class = cls
  43. view.view_initkwargs = initkwargs
  44.  
  45. # take name and docstring from class
  46. update_wrapper(view, cls, updated=())
  47.  
  48. # and possible attributes set by decorators
  49. # like csrf_exempt from dispatch
  50. update_wrapper(view, cls.dispatch, assigned=())
  51. return view
  52.  
  53. def dispatch(self, request, *args, **kwargs):
  54. # Try to dispatch to the right method; if a method doesn't exist,
  55. # defer to the error handler. Also defer to the error handler if the
  56. # request method isn't on the approved list.
  57. if request.method.lower() in self.http_method_names:
  58. handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
  59. else:
  60. handler = self.http_method_not_allowed
  61. return handler(request, *args, **kwargs)
  62.  
  63. def http_method_not_allowed(self, request, *args, **kwargs):
  64. logger.warning(
  65. 'Method Not Allowed (%s): %s', request.method, request.path,
  66. extra={'status_code': 405, 'request': request}
  67. )
  68. return http.HttpResponseNotAllowed(self._allowed_methods())
  69.  
  70. def options(self, request, *args, **kwargs):
  71. """
  72. Handles responding to requests for the OPTIONS HTTP verb.
  73. """
  74. response = http.HttpResponse()
  75. response['Allow'] = ', '.join(self._allowed_methods())
  76. response['Content-Length'] = ''
  77. return response
  78.  
  79. def _allowed_methods(self):
  80. return [m.upper() for m in self.http_method_names if hasattr(self, m)]

四.使用Mixin

  下图引用自:https://www.cnblogs.com/yuanchenqi/articles/8715364.html

  1. 我觉得要理解djangoclass-based-view(以下简称cbv),首先要明白django引入cbv的目的是什么。在django1.3之前,generic view也就是所谓的通用视图,使用的是function-based-viewfbv),亦即基于函数的视图。有人认为fbvcbvpythonic,窃以为不然。python的一大重要的特性就是面向对象。而cbv更能体现python的面向对象。cbv是通过class的方式来实现视图方法的。class相对于function,更能利用多态的特定,因此更容易从宏观层面上将项目内的比较通用的功能抽象出来。关于多态,不多解释,有兴趣的同学自己Google。总之可以理解为一个东西具有多种形态(的特性)。cbv的实现原理通过看django的源码就很容易明白,大体就是由url路由到这个cbv之后,通过cbv内部的dispatch方法进行分发,将get请求分发给cbv.get方法处理,将post请求分发给cbv.post方法处理,其他方法类似。怎么利用多态呢?cbv里引入了mixin的概念。Mixin就是写好了的一些基础类,然后通过不同的Mixin组合成为最终想要的类。
  2.  
  3. 所以,理解cbv的基础是,理解MixinDjango中使用Mixin来重用代码,一个View Class可以继承多个Mixin,但是只能继承一个View(包括View的子类),推荐把View写在最右边,多个Mixin写在左边。

 

五.类视图登陆验证

  1. from django.contrib.auth.decorators import login_required
  2. from django.utils.decorators import method_decorator
  3.  
  4. class FooView(View):
  5.   @method_decorator(login_required)
  6.   def get(request, *args, **kwargs):
  7.     return HttpResponse("hello world")

运维开发笔记整理-基于类的视图(CBV)的更多相关文章

  1. 运维开发笔记整理-Django模型语法

    运维开发笔记整理-Django模型语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.模型基本概念 1>.什么是模型 模型是你的数据唯一的,权威的信息源.它包含你所存储数 ...

  2. 运维开发笔记整理-URL配置

    运维开发笔记整理-URL配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.URL路由 对于高质量的Web应用来说,使用简洁,优雅的URL的路由是一个非常值得重视的细节.Dja ...

  3. 运维开发笔记整理-QueryDict对象

    运维开发笔记整理-QueryDict对象 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 客户端发送数据请求有很多种,相信运维人员已经很清楚了,如果不太清楚的话可以参考我之前的学习笔 ...

  4. 运维开发笔记整理-Request对象与Response对象

    运维开发笔记整理-Request对象与HttpResponse对象 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.request对象 1>.什么是request 首先,我 ...

  5. 运维开发笔记整理-django日志配置

    运维开发笔记整理-django日志配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Django日志 Django使用python内建的logging模块打印日志,Pytho ...

  6. 运维开发笔记整理-创建django用户

    运维开发笔记整理-创建django用户 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.创建普通用户 C:\Users\yinzhengjie\softwares\Pycharm ...

  7. 运维开发笔记整理-template的使用

    运维开发笔记整理-Django的template的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在上一篇博客中我们学习了HttpResponse 和JsonResponse方 ...

  8. 运维开发笔记整理-JsonResponse对象

    运维开发笔记整理-JsonResponse对象 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.使用HttpResponse发送json格式的数据 1>.HttpRespo ...

  9. 运维开发笔记整理-使用Django编写helloworld

    运维开发笔记整理-使用Django编写helloworld 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.创建Django项目 1>.创建Django项目 djang ...

随机推荐

  1. [LeetCode] 381. Insert Delete GetRandom O(1) - Duplicates allowed 插入删除和获得随机数O(1)时间 - 允许重复

    Design a data structure that supports all following operations in average O(1) time. Note: Duplicate ...

  2. 【C/C++开发】STL erase()函数使用要小心

    http://blog.sina.com.cn/s/blog_67b6b720010114d3.html erase()函数的功能是用来删除容器中的元素 删除某个容器里的某个元素:c.erase(T) ...

  3. Apollo环境配置

    一.背景 Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限.流程治理等特性,适用于微服务配置管理 ...

  4. 【转】Fuel-Openstack的搭建(一)

    原文链接:https://blog.csdn.net/qq_35180983/article/details/82181496 2.1安装前的准备操作: 首先,我们需要准备以下操作: 2.1.1 下载 ...

  5. [转帖]央行推出数字货币DCEP:基于区块链技术、将取代现钞

    央行推出数字货币DCEP:基于区块链技术.将取代现钞 天天快报的内容. 密码财经 2019-10-29 18:15 关注   前不久的10月23日,Facebook的首席执行官扎克伯格在美国国会听证会 ...

  6. VS2015如何在同一个解决方案下建立多个项目

    1.先按照常规的方法建一个项目: 2.点击解决方案:右键=>添加=>新建项目 注:本文链接:https://blog.csdn.net/weixin_43081805/article/de ...

  7. Tensorflow基本概念笔记

    一.TensorFlow使用简单,部署快捷 TensorFlow使用数据流图(计算图)来规划计算流程,可以将计算映射到不同的硬件和操作平台.凭借着统一的架构,TensorFlow可以方便的部署剑各种平 ...

  8. lmir 随笔

    近期需要研究一些特征工程的工作,就打算把微软之前公布出来的特征都复现一遍,今天遇到的特征是 LMIR, 其实也就是language model for information retrieval的简写 ...

  9. JavaScript中的原型prototype和__proto__的区别及原型链概念

    问题 初学js的同学,总是搞不清楚js中的原型是什么东西,看着控制台打印出来的一串串__proto__,迷惑不已. 例如我定义一个Person,创建一个实例p,并打印实例. function Pers ...

  10. Linux环境python3.6.5

     安装python3.6可能使用的依赖 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel r ...