【问题标题】:django class view with decorator and sessions带有装饰器和会话的 django 类视图
【发布时间】:2010-11-28 14:17:43
【问题描述】:

我正在尝试将我的一些 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

【问题讨论】:

    标签: django session class views decorator


    【解决方案1】:

    这实际上是 Django - Correct way to pass arguments to CBV decorators? 的副本 它描述了解决这个问题的正确方法。 django 1.9 的正确方法如下:

    @method_decorator(myuser_login_required(), name='dispatch')
    class TopSecretPage(View):
        ..
    

    【讨论】:

      【解决方案2】:

      对应用于任何基于类的视图方法的任何装饰器执行此操作的正确方法是使用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
      

      【讨论】:

      • 你能引用吗?您是说基于类的视图是 django 1.2 所说的执行视图的方式吗?出于维护原因,我已经放弃了基于类的视图。
      • 查看 1.2 发行说明的这一部分:
      • @ThomasSchultz 什么维护原因?您是否建议人们避免基于类的视图,到目前为止我对它们没有任何问题。
      • 我怀疑这更像是一门学科。我们发现基于类的视图往往会快速增长并增加很多复杂性。此外,还有很多开始重复代码的诱惑。然后你开始拥有像“基础”视图类和东西这样的东西。我们发现我们可以使用更易于维护、更简单且更易于调试的函数视图。只是我们的经验。类视图确实有效,我们使用了将近 2 年。
      【解决方案3】:

      问题是你的包装器期望“request”作为第一个参数,但类上的方法总是将“self”作为第一个参数。所以在你的装饰器中,它认为的请求对象实际上是 TopSecretPage 本身。

      无论是 Vinay 还是 artran 的解决方案都应该有效,所以我不会重复它们。只是认为对问题进行更清晰的描述可能会有所帮助。

      【讨论】:

        【解决方案4】:

        您可以装饰 url,而不是在视图上使用装饰器。

        例如在 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), {}),
        )
        

        您可能需要稍微尝试一下,但它是正确的。

        【讨论】:

        • 我认为这个解决方案应该可以,但你需要实例化TopSecretPage:myuser_login_required(TopSecretPage())
        【解决方案5】:

        这个问题已经出现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
        

        【讨论】:

        • 嗯,就像我说我的 oop 技能很弱一样,我实际上在发布这个问题之前就读过了。从该示例中,我看不到如何访问装饰器函数中的请求对象。
        • 感谢更新!但我还是有问题哈哈。我会更新我的问题以尝试显示它...
        • 对于 Django 1.5,它是 @method_decorator(cache_control(max_age=86400)) def get(self, request, *args, **kwargs):
        猜你喜欢
        • 2020-12-01
        • 1970-01-01
        • 2016-08-14
        • 2019-02-24
        • 2011-02-06
        • 2017-03-08
        • 2015-03-07
        • 2014-10-20
        • 2018-10-18
        相关资源
        最近更新 更多