假设我创建了一个(希望)可重用的应用96
:
urls.py
D
和fooapp的views.py:
fooapp
由于它是可重复使用的应用,因此未指定任何访问控制(例如urls('^(?P<userid>\d+)/$', views.show_foo),
)。
在网站/项目urls.py中,包含以下应用:
def show_foo(request, userid):
usr = shortcuts.get_object_or_404(User, pk=userid)
... display a users' foo ...
return render_to_response(...)
我如何/在哪里可以指定在本网站中,只有工作人员才有权查看用户的foo?
除了工作人员之外,用户是否应该能够查看自己的foo(@login_required
+ urls('^foo/', include('fooapp.urls')),
)?
我没有找到任何明显的参数来包括..
注意:这与访问控制有关,而不是权限,即login_required
检查request.user.id == userid
,require_staff
检查是否记录了User.is_staff
在上面描述了用户查看他们自己的页面。此问题涉及网站如何为可重用应用程序指定访问控制。
答案 0 :(得分:0)
好吧,我通过迭代Django include
返回的模式找到了一种方法:
from django.core.urlresolvers import RegexURLPattern, RegexURLResolver
def urlpatterns_iterator(patterns):
"""Recursively iterate through `pattern`s.
"""
_patterns = patterns[:] # create a copy
while _patterns:
cur = _patterns.pop()
if isinstance(cur, RegexURLPattern):
yield cur
elif isinstance(cur, RegexURLResolver):
_patterns += cur.url_patterns
else:
raise ValueError("I don't know how to handle %r." % cur)
def decorate(fn, (urlconf_module, app_name, namespace)):
"""Iterate through all the urls reachable from the call to include and
wrap the views in `fn` (which should most likely be a decorator).
(the second argument is the return value of Django's `include`).
"""
# if the include has a list of patterns, ie.: url(<regex>, include([ url(..), url(..) ]))
# then urlconf_module doesn't have 'urlpatterns' (since it's already a list).
patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
for pattern in urlpatterns_iterator(patterns):
# the .callback property will set ._callback potentially from a string representing the path to the view.
if pattern.callback:
# the .callback property doesn't have a setter, so access ._callback directly
pattern._callback = fn(pattern._callback)
return urlconf_module, app_name, namespace
然后在网站/项目的urls.py中使用它,而不是:
urls('^foo/', include('fooapp.urls')),
一个人会做:
from django.contrib.admin.views.decorators import staff_member_required as _staff_reqd
def staff_member_required(patterns): # make an include decorator with a familiar name
return decorate(_staff_reqd, patterns)
...
urls('^foo/', staff_member_required(include('fooapp.urls'))),