当前位置: 首页 > 面试题库 >

是否可以用login_required装饰Django URL中的include(…)?

权兴为
2023-03-14
问题内容

我在网站上有一些限制区域,我想为此指定login_required装饰器。但是我想对每个包含在主urls.py中的对象执行一次操作,而不是对包含在urls.py中的每个单独的URL进行一次操作。

所以代替:

/private/urls.py:

(r'^profile/$', login_required(profile)),

我会做一些事情:

/urls.py

urlpatterns = patterns('',
                      ...
                      (r'^private/', login_required(include('private'))),
                      )

不幸的是,除了它不起作用。


问题答案:

这是可行的,实际上我为此找到了两个 片段。

解决方案1
棉花替代品的第一个片段,RegexURLPattern以及RegexURLResolver在resolve通话期间注入给定装饰器的自定义实现。

from django.core.urlresolvers import RegexURLPattern, RegexURLResolver
from django.conf.urls.defaults import patterns, url, include
from django.contrib import admin
from myproject.myapp.decorators import superuser_required

class DecoratedURLPattern(RegexURLPattern):
    def resolve(self, *args, **kwargs):
        result = super(DecoratedURLPattern, self).resolve(*args, **kwargs)
        if result:
            result.func = self._decorate_with(result.func)
        return result

class DecoratedRegexURLResolver(RegexURLResolver):
    def resolve(self, *args, **kwargs):
        result = super(DecoratedRegexURLResolver, self).resolve(*args, **kwargs)
        if result:
            result.func = self._decorate_with(result.func)
        return result

def decorated_includes(func, includes, *args, **kwargs):
    urlconf_module, app_name, namespace = includes

    for item in urlconf_module:
        if isinstance(item, RegexURLPattern):
            item.__class__ = DecoratedURLPattern
            item._decorate_with = func

        elif isinstance(item, RegexURLResolver):
            item.__class__ = DecoratedRegexURLResolver
            item._decorate_with = func

    return urlconf_module, app_name, namespace

你需要像这样使用它:

urlpatterns = patterns('',
    # ...
    (r'^private/', decorated_includes(login_required, include(private.urls))),
)

(请注意,include此方法不能将参数作为字符串。)

解决方案#2
sjzabel的另一个解决方案(我最终使用了我自己)在外部 patterns调用中应用,因此可以与字符串一起使用,并且语法略有不同。但是,想法是一样的。

def required(wrapping_functions,patterns_rslt):
    '''
    Used to require 1..n decorators in any view returned by a url tree

    Usage:
      urlpatterns = required(func,patterns(...))
      urlpatterns = required((func,func,func),patterns(...))

    Note:
      Use functools.partial to pass keyword params to the required 
      decorators. If you need to pass args you will have to write a 
      wrapper function.

    Example:
      from functools import partial

      urlpatterns = required(
          partial(login_required,login_url='/accounts/login/'),
          patterns(...)
      )
    '''
    if not hasattr(wrapping_functions,'__iter__'): 
        wrapping_functions = (wrapping_functions,)

    return [
        _wrap_instance__resolve(wrapping_functions,instance)
        for instance in patterns_rslt
    ]

def _wrap_instance__resolve(wrapping_functions,instance):
    if not hasattr(instance,'resolve'): return instance
    resolve = getattr(instance,'resolve')

    def _wrap_func_in_returned_resolver_match(*args,**kwargs):
        rslt = resolve(*args,**kwargs)

        if not hasattr(rslt,'func'):return rslt
        f = getattr(rslt,'func')

        for _f in reversed(wrapping_functions):
            # @decorate the function from inner to outter
            f = _f(f)

        setattr(rslt,'func',f)

        return rslt

    setattr(instance,'resolve',_wrap_func_in_returned_resolver_match)

    return instance

这样称呼它:

urlpatterns = patterns('',
    # ...
)

urlpatterns += required(
    login_required,
    patterns('',
        (r'^private/', include('private.urls'))
    )
)

两者都能正常工作,但我更喜欢后一种语法。



 类似资料:
  • 问题内容: django中是否有一个类似于@login_required的装饰器,它也可以测试用户是否是超级用户? 谢谢 问题答案: 使用装饰器:

  • 问题内容: 也许这是一个可怕的主意,但如果是这样,请告诉我为什么,然后假装这是一项学术活动,不会在生产中日渐成熟。 我想在Angular $ injector服务中添加一些逻辑,以监视何时将某些服务注入到其他服务中。由于Angular似乎提供了一种装饰服务的机制,因此我认为这是可行的方法。但是,以下代码将引发错误。 具体错误是: 未捕获的错误:[$ injector:modulerr]由于以下原因

  • 问题内容: 在编写一些视图以响应Ajax请求时,我发现login_required装饰器对于未通过身份验证的用户始终返回302状态代码有些奇怪。由于这些视图是ajax视图,因此这似乎有些不合适。我不希望用户在这种情况下登录,但是我希望Django告诉客户端访问此视图需要身份验证(我认为401应该是正确的状态代码)。 为了实现这一目标,我开始编写自己的装饰器login_required_ajax,但

  • 我试图理解decorator是如何工作的,我想知道一个修饰过的函数是否可以访问decorator的变量。例如,在下面的代码中,如何使f1能够访问localVariable?这可能吗?这是一种很好的做事方式吗?

  • AccessibilityService在系统的内存管理方面与普通服务有何不同? 我想问的是:系统可以为了节省内存而关闭AccessibilityService吗?如果可以,当您进入AccessibilityService时,您会看到它打开还是关闭?用户是否必须再次手动打开? 使用startForeground是否有助于使AccessibilityService保持活动状态? 在一个类似的问题中,