本文整理自网络,侵删。
基于类的视图简介
基于类的视图提供了一种将视图实现为Python对象而非函数的替代方法。它们不能替代基于功能的视图,但是与基于功能的视图相比具有某些区别和优势:
- 与特定HTTP方法(GET,POST等)相关的代码组织可以通过单独的方法而不是条件分支来解决。
- 诸如mixin(多重继承)之类的面向对象技术可用于将代码分解为可重用的组件。
通用视图,基于类的视图和基于类的通用视图的关系和历史记录
开始时只有视图函数协定,Django将您的函数传递给,HttpRequest并期望将 传递给HttpResponse。这就是Django提供的功能。
早期就认识到在视图开发中发现了常见的习惯用法和模式。引入了基于函数的通用视图,以抽象化这些模式并简化常见情况下的视图开发。
基于函数的通用视图的问题在于,尽管它们很好地涵盖了简单的情况,但无法扩展或自定义某些配置选项之外的视图,从而限制了它们在许多实际应用程序中的用途。
创建基于类的通用视图的目的与基于函数的通用视图相同,以使视图开发更加容易。但是,通过使用mixins来实现解决方案的方式提供了一个工具包,该工具包使得基于类的通用视图比基于功能的对应视图更具可扩展性和灵活性。
如果您过去曾经尝试过基于函数的通用视图,但发现缺少这些功能,则不应将基于类的通用视图视为基于类的等效视图,而应将其视为解决通用视图旨在解决的原始问题的全新方法。解决。
Django用于构建基于类的泛型视图的基类和mixin工具包的构建具有最大的灵活性,因此,它们具有默认方法实现和属性形式的许多钩子,您可能不会在最简单的用法中关注它们案件。例如,实现不是form_class使用get_form方法的基于类的属性,而是使用了一种方法,该get_form_class方法调用一种方法,该方法在其默认实现中返回form_class类的属性。这为您提供了几个选项,用于指定从属性到完全动态,可调用的钩子使用哪种形式。对于简单情况,这些选项似乎增加了空心的复杂性,但是如果没有这些选项,则会限制更高级的设计。
使用基于类的意见
从本质上讲,基于类的视图使您可以使用不同的类实例方法来响应不同的HTTP请求方法,而不是使用单个视图函数中的有条件分支代码。
因此,GET在视图函数中用于处理HTTP的代码如下所示:
from django.http import HttpResponse
?
def my_view(request):
if request.method == 'GET':
# <view logic>
return HttpResponse('result')
在基于类的视图中,这将变为:
from django.http import HttpResponse
from django.views import View
?
class MyView(View):
def get(self, request):
# <view logic>
return HttpResponse('result')
因为Django的URL解析器希望将请求和关联的参数发送给可调用的函数而不是类,所以基于类的视图具有一个 as_view()class方法,该类方法返回一个函数,该请求可以在请求到达与关联模式匹配的URL时被调用。该函数创建该类的实例,调用 setup()以初始化其属性,然后调用其dispatch()方法。 dispatch查看该请求以确定它是否为GET, POST等,并将请求转发给匹配的方法(如果已定义),否则将其引发HttpResponseNotAllowed:
# urls.py
from django.urls import path
from myapp.views import MyView
?
urlpatterns = [
path('about/', MyView.as_view()),
]
值得注意的是,您的方法返回的内容与您从基于函数的视图返回的内容相同,即的某种形式 HttpResponse。这意味着 http快捷方式或 TemplateResponse对象可在基于类的视图中有效使用。
尽管最小的基于类的视图不需要任何类属性即可执行其工作,但是类属性在许多基于类的设计中很有用,并且有两种配置或设置类属性的方法。
第一种是子类化和覆盖子类中的属性和方法的标准Python方法。这样,如果您的父类具有这样的属性 greeting:
from django.http import HttpResponse
from django.views import View
?
class GreetingView(View):
greeting = "Good Day"
?
def get(self, request):
return HttpResponse(self.greeting)
您可以在子类中覆盖它:
class MorningGreetingView(GreetingView):
greeting = "Morning to ya"
另一个选择是将类属性配置为as_view()URLconf中的调用的关键字参数 :
urlpatterns = [
path('about/', GreetingView.as_view(greeting="G'day")),
]
注意:在为分配给它的每个请求实例化您的类时,通过as_view()导入点设置的类属性 在导入URL时仅配置一次。
使用混入
Mixins是多重继承的一种形式,可以将多个父类的行为和属性进行组合。
例如,在基于通用类的视图中,有一个mixin, TemplateResponseMixin其主要目的是定义method render_to_response()。当与View 基类的行为组合时,结果是一个TemplateView 类,该类会将请求分派到适当的匹配方法(View基类中定义的行为),并且具有 render_to_response() 使用 template_name 属性返回TemplateResponse 对象(行为)的方法。 )中定义TemplateResponseMixin。
Mixins是在多个类之间重用代码的绝佳方法,但是它们会带来一些成本。您的代码散布在mixin中的次数越多,读取子类并了解其确切操作的难度就越大,而如果您正在子类化具有深层继承树。
相关阅读 >>
更多相关阅读请进入《Django》频道 >>

Python编程 从入门到实践 第2版
python入门书籍,非常畅销,超高好评,python官方公认好书。