我正在将一些带有信号的FBV转换为CBV,所以我有这个装饰器:
def ensure_https(view_func):
def _checkssl(request, *args, **kwargs):
print request.is_secure()
if not settings.DEBUG and not request.is_secure():
url_str = request.build_absolute_uri()
url_str = url_str.replace('http://', 'https://')
return HttpResponseRedirect(url_str)
return view_func(request, *args, **kwargs)
return _checkssl
并将其添加到基于类的视图中的函数中,如下所示:
class ExampleTemplateView(TemplateView):
template_name = 'example.html'
@ensure_https
def dispatch(self, request, *args, **kwargs):
...
return HttpResponseRedirect(/hello/')
但是我收到以下错误:
'ExampleTemplateView' object has no attribute 'is_secure'
然而,当我在基于函数的视图上使用这个装饰器时,它工作得很好。我应该使用特定的CBV吗?
如果您需要更多代码或信息,请告知我们。谢谢你的帮助!
答案 0 :(得分:1)
我认为您的signal
和decorator
混淆了,因为代码中的模式是decorator
。根据您正在做的事情,可能有更好的替代方法来放置URL重定向逻辑。我在想网络服务器(nginx),HTTP Strict Transport Security
HTTP header或middleware。话虽如此,from the django docs:
要装饰基于类的视图的每个实例,您需要进行装饰 类定义本身。要执行此操作,请将装饰器应用于 类的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(ProtectedView, self).dispatch(*args, **kwargs)