面向对象的技术例如Mixin(多继承)可以将代码分解成可重用的组件。
Mixin 是多继承的一种形式,其来自多个父类的行为和属性可以组合在一起。
例如,在通用的基于类的视图中,有一个Mixin
叫做 TemplateResponseMixin
,它的主要目的是定义render_to_response()
方法。它与View
基类的组合是TemplateView
类,这个类可以调度请求给正确的方法(View
基类中定义的行为),同时还具有一个render_to_response()
方法,该方法使用template_name
属性来返回一个TemplateResponse
对象( TemplateResponseMixin
中定义的行为)。
Mixin
是重用多个类的代码的一种极好的方法,但是它们需要一些代价。代码在Mixin
中越分散,子类将越难阅读并知道它的行为;如果你的继承很深,将难以知道应该覆盖哪一个Mixin
的方法。
还要注意,只能继承一个通用视图 —— 也就是说,只能有一个父类继承View
,其它的父类必须是Mixin
。继承多个继承自View
的类 将不能像预期的那样工作—— 例如,试图在一个列表的顶部使用表单而组合ProcessFormView
和ListView
。
举个栗子,在验证用户登录状态的时候,一方面我们可以使用Django提供的装饰器@login_required
,还可以自己尝试写一个函数验证用户的登录状态。
我们可以在util中自定义一个用于验证用户是否登录的类,每个需要用户登录后才能进行的操作,我们都要继承于这个类,下面是mixin_utils.py
这里我们使用了装饰器@method_decorator
在course/views.py
中,每次用户点击我要学习都必须是登录的状态,所以需要这样写:
基于类的视图处理表单
一个基本的用于处理表单的视图函数可能是这样的:
我们首先要定义表单的字段,在这里是MyForm
,在视图函数中我们将其实例化,在request
中取出数据填入到表单中,并将其存储到数据库中,最后我们还将表单返回给前端页面。
一个基于类的视图看上去是这样的:
还可以在URLconf中装饰基于类的视图,举个例子:
装饰类
若要装饰基于类的视图的每个实例,你需要装饰类本身。可以将装饰器运用到类的dispatch()
方法上来实现这点。
类的方法和独立的函数不完全相同,所以你不可以直接将函数装饰器运用到方法上 —— 你首先需要将它转换成一个方法装饰器。method_decorator
装饰器将函数装饰器
转换成方法装饰器
,这样它就可以用于实例方法上。
在这个例子中,ProtectedView 的每个实例都将有登录保护。