可重复使用的应用程序和访问控制

时间:2015-12-08 15:18:36

标签: python django

假设我创建了一个(希望)可重用的应用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 == useridrequire_staff检查是否记录了User.is_staff在上面描述了用户查看他们自己的页面。此问题涉及网站如何为可重用应用程序指定访问控制。

1 个答案:

答案 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'))),