未加星标

认识Django的Class-Based-View

字体大小 | |
[开发(python) 所属分类 开发(python) | 发布者 店小二04 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

学习Django非常简单,几乎不用花什么精力就可以入门了。配置一个url,分给一个函数处理它,返回 response ,几乎都没有什么很难理解的地方。

写多了,有些问题才逐渐认识到。比如有一个view比较复杂,调用了很多其他的函数。想要把这些函数封装起来,怎么办?当然,可以用注释 #------view------ 这样将函数隔离开,这种方法太low了,简直是在骗自己,连封装都算不上。

python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:

提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承) 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性 使用class-based views

如果我们要写一个处理GET方法的view,用函数写的话是下面这样。

from django.httpimport HttpResponse def my_view(request): if request.method == 'GET': # <view logic> return HttpResponse('result')

如果用class-based view写的话,就是下面这样。

from django.httpimport HttpResponse from django.viewsimport View class MyView(View): def get(self, request): # <view logic> return HttpResponse('result')

Django的url是将一个请求分配给可调用的函数的,而不是一个class。针对这个问题,class-based view提供了一个 as_view() 静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用 dispatch() 方法, dispatch() 方法会根据request的method的不同调用相应的方法来处理request(如 get() , post() 等)。到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。

在url中,就这么写:

# urls.py from django.conf.urlsimport url from myapp.viewsimport MyView urlpatterns = [ url(r'^about/$', MyView.as_view()), ]

类的属性可以通过两种方法设置,第一种是常见的Python的方法,可以被子类覆盖。

from django.httpimport HttpResponse from django.viewsimport View class GreetingView(View): greeting = "Good Day" def get(self, request): return HttpResponse(self.greeting) # You can override that in a subclass class MorningGreetingView(GreetingView): greeting = "Morning to ya"

第二种方法,你也可以在url中指定类的属性:

urlpatterns = [ url(r'^about/$', GreetingView.as_view(greeting="G'day")), ] 使用Mixin

Django中使用Mixin来重用代码,一个View Class可以继承多个Mixin,但是只能继承一个View(包括View的子类),推荐把View写在最右边,多个Mixin写在左边。Mixin也是比较复杂的技术,本文不详细说了,以后写一篇针对Mixin的文章吧。

使用装饰器

在CBV中,可以使用 method_decorator 来装饰方法。

from django.contrib.auth.decoratorsimport login_required from django.utils.decoratorsimport method_decorator from django.views.genericimport TemplateView class ProtectedView(TemplateView): template_name = 'secret.html' @method_decorator(login_required) def dispatch(self, *args, **kwargs): return super(ProtectedView, self).dispatch(*args, **kwargs)

也可以写在类上面,传入方法的名字。

@method_decorator(login_required, name='dispatch') class ProtectedView(TemplateView): template_name = 'secret.html'

如果有多个装饰器装饰一个方法,可以写成一个list。例如,下面这两种写法是等价的。

decorators = [never_cache, login_required] @method_decorator(decorators, name='dispatch') class ProtectedView(TemplateView): template_name = 'secret.html' @method_decorator(never_cache, name='dispatch') @method_decorator(login_required, name='dispatch') class ProtectedView(TemplateView): template_name = 'secret.html' 参考资料 Introduction to class-based views Django 1.6 最佳实践: 如何正确使用 CBVs (Class-based views)

本文开发(python)相关术语:python基础教程 python多线程 web开发工程师 软件开发工程师 软件开发流程

主题: DjangoPython
分页:12
转载请注明
本文标题:认识Django的Class-Based-View
本站链接:http://www.codesec.net/view/530674.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 开发(python) | 评论(0) | 阅读(15)