代码之家  ›  专栏  ›  技术社区  ›  Krystian Cybulski

Django模板能否知道从其调用的视图是否需要@login_修饰符?

  •  5
  • Krystian Cybulski  · 技术社区  · 17 年前

    假设我有一个系统,它有一些公共页面(非认证用户和登录用户都可以查看),还有一些只有登录用户才能查看的页面。

    我希望模板为这两类页面显示稍微不同的内容。@login_required view decorator始终用于只有登录用户才能查看的视图。但是,我的模板需要知道这个修饰符是否用于从中调用模板的视图。

    请记住,我不关心用户是否登录公共页面。我关心的是一个页面是否能被公众看到,如果没有一个@login_所需的装饰器,我就会知道这一点。

    是否有人能给我一个提示,告诉我模板如何知道在从中调用模板的视图上是否使用了特定的装饰器?

    4 回复  |  直到 17 年前
        1
  •  5
  •   Jarret Hardie    17 年前

    是的,这是可能的,但不是非常简单。复杂的因素是姜戈的 login_required decorator实际上通过两个间接级别(一个动态函数和一个其他decorator),最终到达django.contrib.auth.decorators._checklogin,这是一个带有 __call__ 方法。

    假设您有一个非Django花园风格的装饰功能,如下所示:

    def my_decorator(func):
        def inner():
            return func()
        return inner
    
    @my_decorator
    def foo():
        print foo.func_name
    
    # results in: inner
    

    检查功能 foo 已经包装的可以像检查函数对象的名称一样简单。您可以在函数内部执行此操作。名称实际上是最后一个包装函数的名称。对于更复杂的情况,可以使用 inspect 如果您正在寻找某个特定的内容,则从当前框架向上遍历外部框架的模块。

    然而,对于django,事实上decorator实际上是 _CheckLogin 类意味着函数不是真正的函数,因此没有 func_name 属性:尝试上述代码将引发异常。

    查看的源代码 django.contrib.auth.decorators._CheckLogin 然而,这表明 检查登录 实例将具有 login_url 财产。这是一个非常简单的测试方法:

    @login_required
    def my_view(request):
        is_private = hasattr(my_view, 'login_url')
    

    因为 检查登录 也用于实现其他auth修饰符,此方法也适用于 permission_required 等等,我从来没有真正需要使用这个,但是,我真的不能评论你应该寻找什么,如果你有多个装饰围绕一个视图…一个留给读者的练习,我想(检查帧堆栈?).

    然而,作为一个未经请求的编辑建议,我会说检查函数本身,看看它是否像这样被包装起来,让我觉得有点心烦意乱。你可以想象当一个新开发人员来到这个项目时,会有各种不可预知的行为等待着发生,就像扇了其他装修工的耳光。事实上,您还将面临Django框架本身的更改…等待发生的安全风险。

    出于这个原因,我建议将van gale的方法作为一种明确的方法,因此实现更加健壮。

        2
  •  3
  •   Van Gale    17 年前

    我将在模板中传递一个额外的上下文变量。

    因此,需要@login_的视图将传递如下变量: private: True 其他观点也会通过 private: False

        3
  •  1
  •   Blair Conrad    17 年前

    为什么你的模板需要知道这个?如果 @login_required 使用decorator时,视图本身会阻止未登录的用户访问页面,因此从不会看到要开始使用的模板。

        4
  •  0
  •   David Webb    17 年前

    模板是分层的,所以为什么不 @login_required 版本和“否” 要求登录 “版本,这两个版本都继承自同一父版本?

    这样可以使模板更干净,更容易维护。

    推荐文章