基于类的视图简介


当前第2页 返回上一页

还要注意,您只能从一个通用视图继承-也就是说,只有一个父类可以继承,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 简介

错误报告

Django的缓存框架

部署清单

内置基于类的通用视图

Django 使用表单模板

Django 模板

使用asgi进行部署

Django 的安全性

Django 模型

更多相关阅读请进入《Django》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...