还要注意,您只能从一个通用视图继承-也就是说,只有一个父类可以继承,View其余(如果有)应该是mixins。尝试从多个继承的类中进行继承View-例如,尝试使用列表顶部的表单并组合ProcessFormView和 ListView-将无法按预期工作。
使用基于类的视图处理表单
处理表单的基于函数的基本视图可能如下所示:
from django.http import HttpResponseRedirect
from django.shortcuts import render
?
from .forms import MyForm
?
def myview(request):
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
# <process form cleaned data>
return HttpResponseRedirect('/success/')
else:
form = MyForm(initial={'key': 'value'})
?
return render(request, 'form_template.html', {'form': form})
类似的基于类的视图可能类似于:
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.views import View
?
from .forms import MyForm
?
class MyFormView(View):
form_class = MyForm
initial = {'key': 'value'}
template_name = 'form_template.html'
?
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
?
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
# <process form cleaned data>
return HttpResponseRedirect('/success/')
?
return render(request, self.template_name, {'form': form})
这是一个最小的情况,但是您可以看到您可以通过覆盖任何类属性(例如form_class,通过URLconf配置,或子类化并覆盖一个或多个方法(或两者)!)来定制此视图 。 。
装饰基于类的视图
基于类的视图的扩展不仅限于使用混合。您也可以使用装饰器。由于基于类的视图不是函数,因此根据您正在使用as_view()还是创建子类来装饰它们的工作方式有所不同。
在URLconf中装饰
您可以通过装饰as_view()方法的结果来调整基于类的视图 。最简单的方法是在部署视图的URLconf中:
from django.contrib.auth.decorators import login_required, permission_required from django.views.generic import TemplateView from .views import VoteView urlpatterns = [ path('about/', login_required(TemplateView.as_view(template_name="secret.html"))), path('vote/', permission_required('polls.can_vote')(VoteView.as_view())), ]
此方法基于每个实例应用装饰器。如果要装饰视图的每个实例,则需要采用其他方法。
装饰类
要修饰基于类的视图的每个实例,您需要修饰类定义本身。为此,您可以将装饰器应用于dispatch()类的 方法。
类上的方法与独立函数并不完全相同,因此您不能仅将函数装饰器应用于该方法–您需要首先将其转换为方法装饰器。所述method_decorator装饰来转换函数装饰成方法装饰,使得它可以在一个实例方法中。例如:
from django.contrib.auth.decorators import login_required from django.utils.decorators import method_decorator from django.views.generic import TemplateView class ProtectedView(TemplateView): template_name = 'secret.html' @method_decorator(login_required) def dispatch(self, *args, **kwargs): return super().dispatch(*args, **kwargs)
或者,更简洁地说,您可以代替装饰类,并将要装饰的方法的名称作为关键字参数传递name:
@method_decorator(login_required, name='dispatch') class ProtectedView(TemplateView): template_name = 'secret.html'
如果您在多个地方使用了一组通用装饰器,则可以定义一个装饰器列表或元组,然后使用它而不是method_decorator()多次调用 。这两个类是等效的:
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'
装饰者将按照传递给装饰者的顺序处理请求。在示例中,never_cache()将在之前处理请求 login_required()。
在此示例中,的每个实例都ProtectedView将具有登录保护。这些示例使用login_required,但是通过使用可以获得相同的行为 LoginRequiredMixin。
注意:method_decorator将*args和**kwargs 作为参数传递给类中经过修饰的方法。如果您的方法不接受一组兼容的参数,它将引发 TypeError异常。
详情参考: https://docs.djangoproject.com/en/3.0/
标签:Django
相关阅读 >>
更多相关阅读请进入《Django》频道 >>

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