django - Django如何扩展通用视图类
问题描述
我注意到我正在为我网站上的许多视图设置站点范围的上下文变量和请求变量。自然,这种情况需要继承。如果我所有的基于视图类的视图都继承自 SiteView 而不是通用视图,我可以将所有共性分解到 SiteView 子类中。然后我可以从 SiteView 继承我所有的视图。但是,我不能让它工作。这是我的代码:
from django.contrib.auth.decorators import login_required
from django.views.generic import View
from django.utils.decorators import method_decorator
class SiteView(View):
''' Extends the generic django-supplied View class '''
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(SiteView, self).dispatch(*args, **kwargs)
def get(self, *args, **kwargs):
''' Adds the variables required in the get request '''
context = super(SiteView, self).get(*args, **kwargs)
context['common_var'] = 'some common value'
context['user'] = request.user
return self.render_to_response(context)
这会引发以下类型错误:
dispatch() missing 1 required positional argument: 'request'
任何帮助,将不胜感激
编辑:即使标记了正确答案,代码也存在其他问题。特别是,SiteView 的 get 方法不应该有以下行:
context = super(SiteView, self).get(*args, **kwargs)
这是因为 View 类没有任何 get 方法。
解决方案
您忘记将请求传递给super().dispatch(..)
调用:
class SiteView(View):
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(SiteView, self).dispatch(request, *args, **kwargs)
或者你可以省略参数request
中的dispatch
,从而通过*args
and传递它**kwargs
:
class SiteView(View):
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(SiteView, self).dispatch(*args, **kwargs)
然而,传递函数的名称可能更优雅,例如:
@method_decorator(login_required, name='dispatch')
class SiteView(View):
# ...
编辑:请注意 aView
没有get(..)
,post(..)
等方法。该dispatch(..)
方法将查看是否存在此类方法,如果存在则重定向到它。如果这样的方法不存在,它将返回“405 Method Not Allowed”响应。
因此,您的get(..)
功能可以像这样实现:
@method_decorator(login_required, name='dispatch')
class SiteView(View):
''' Extends the generic django-supplied View class '''
def render_to_response(self, context):
# ...
def get(self, request, *args, **kwargs):
context = {
'common_var': 'some common value',
'user': request.user
}
return self.render_to_response(context)
实现“mixin”可能更有意义(也许使用LoginRequiredMixin
mixin [Django-doc]的子类。
例如像:
class SiteViewMixin(LoginRequiredMixin):
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context.update(common_var='some common value', user=self.request.user)
return context
然后在另一个视图中使用 mixin,例如:
class SomeView(SiteViewMixin, TemplateView):
# ...
推荐阅读
- python - 使用 elementtree 从目录解析 xml 文件
- android - ProgressBar 是否有一个 xml 属性来禁用用户交互?
- c# - 滚动条不起作用 - Selenium Webdriver
- javascript - 如何使用 jquery 在点击时显示动态数据
- regex - 对话流实体名称的正则表达式验证
- php - PHP文件忽略引导表设计
- python - 如何在python中获得以下输出
- python - 清理 csv 数据,w/pandas 有没有办法找到可以转换为 # 的第一个 obj 列?
- python - Homebrew 没有安装正确版本的 Python
- templates - 应用新式网站模板时的 SharePoint Online 错误消息