gpt4 book ai didi

django - 是否可以使用 login_required 修饰 django url 中的 include(...)?

转载 作者:行者123 更新时间:2023-11-28 19:35:10 26 4
gpt4 key购买 nike

我在站点上有一些限制区域,我想为其指定 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'))),
)

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

最佳答案

这是可行的,事实上我刚刚找到two snippets为了这。

解决方案 #1

cotton 的第一个片段将 RegexURLPatternRegexURLResolver 替换为在 resolve 调用期间注入(inject)给定装饰器的自定义实现。

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 的另一个解决方案,我最终自己使用了它,在 outside 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 修饰 django url 中的 include(...)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2307926/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com