我正在尝试将我的一些django视图从基于函数的视图转换为基于类的视图,我遇到了一个小问题。
我的OO有点弱,我认为问题在于我已经忘记了事情的发展方向。
我在视图中需要一个自定义登录装饰器,所以我有......
首先我从这个例子中得到了View类 http://www.djangosnippets.org/snippets/760/
然后我的视图类看起来像这样......
class TopSecretPage(View):
@custom_login
def __call__(self, request, **kwargs):
#bla bla view stuff...
pass
问题是我的装饰者由于某种原因无法访问request.session ...
我的装饰师看起来像这样......
def myuser_login_required(f):
def wrap(request, *args, **kwargs):
# this check the session if userid key exist,
# if not it will redirect to login page
if 'field' not in request.session.keys():
return wrap
我认为这很简单,我很遗憾,所以感谢大家的耐心!
更新: 好的,这就是我得到的错误......
“ViewDoesNotExist:在模块projectname.application.views中尝试过TopSecretPage。错误是:类型对象'TopSecretPage'没有属性'session'”
我简化了装饰器,看起来像这样....
def myuser_login_required(request, *args, **kwargs):
# this check the session if userid key exist,
# if not it will redirect to login page
if 'username' not in request.session.keys():
return HttpResponseRedirect(reverse("login-page"))
return True
答案 0 :(得分:6)
对应用于任何基于类的视图方法的任何装饰器执行此操作的正确方法是使用django.utils.decorators.method_decorator()
。我不确定何时引入了method_decorator(),但这是Django 1.2 release notes中的示例/更新。像这样使用它:
from django.utils.decorators import method_decorator
class TopSecretPage(View):
@method_decorator(custom_login)
def __call__(self, request, **kwargs):
#bla bla view stuff...
pass
答案 1 :(得分:2)
此问题已出现before。包含一个可能适合您的解决方案。
更新:装饰器的示例方法:
class ContentView(View):
# the thing in on_method() is the actual Django decorator
#here are two examples
@on_method(cache_page(60*5))
@on_method(cache_control(max_age=60*5))
def get(self, request, slug): # this is the decorated method
pass #in here, you access request normally
答案 2 :(得分:2)
问题是你的包装器期望“request”作为第一个参数,但是类上的方法总是将“self”作为第一个参数。所以在你的装饰器中,它认为请求对象实际上是TopSecretPage本身。
无论是Vinay还是artran的解决方案都应该有效,所以我不再重复了。只是想更清楚地描述问题可能会有所帮助。
答案 3 :(得分:1)
您可以装饰网址,而不是在视图上使用装饰器。
例如在urls.py中:
from my_decorators import myuser_login_required
from my_views import TopSecretPage
urlpatterns = patterns('',
(r'^whatever-the-url-is/$', myuser_login_required(TopSecretPage), {}),
)
你可能需要稍微玩一下,但这是正确的。
答案 4 :(得分:1)
这实际上是Django - Correct way to pass arguments to CBV decorators?的副本 它描述了解决这个问题的正确方法。 django 1.9的正确方法如下:
@method_decorator(myuser_login_required(), name='dispatch')
class TopSecretPage(View):
..