2015-12-08 4 views
3

Допустим, я создал (надеюсь) многоразовое приложение, fooapp:многоразовых приложений и контроль доступа

urls.py

urls('^(?P<userid>\d+)/$', views.show_foo), 

и views.py приложения Foo в:

def show_foo(request, userid): 
    usr = shortcuts.get_object_or_404(User, pk=userid) 
    ... display a users' foo ... 
    return render_to_response(...) 

Поскольку это приложение многократного использования, оно не указывает никакого контроля доступа (например, @login_required).

В urls.py сайта/проекта, приложение входит:

urls('^foo/', include('fooapp.urls')), 

Как/где я могу указать, что в этом месте только сотрудники должны быть предоставлен доступ, чтобы увидеть Foo пользователя?

Как насчет того, если в дополнение к сотрудникам пользователи должны иметь возможность просматривать свои собственные foo (login_required + request.user.id == userid)?

я не нашел каких-либо очевидных параметров включить ..

Примечание: это связано с контролем доступа, а не разрешения, т.е. require_staffUser.is_staff чеки, чеки login_required если request.user авторизован, и пользователь -view-their-own-page описан выше. Этот вопрос касается того, как сайт может указывать контроль доступа для многоразового приложения.

+0

Возможный дубликат [Как использовать Django группы и завивка isions?] (http://stackoverflow.com/questions/4778685/how-do-i-use-django-groups-and-permissions) – maazza

+3

Я предполагаю, что правильный способ сделать это - предоставить параметры конфигурации, такие как 'FOO_ALLOW_USER_VIEW' или 'FOO_REQUIRE_STAFF' с некоторыми значениями по умолчанию, которые вы предоставляете, которые могут быть перезаписаны в конфигурации сайтов. – Maciek

+0

@maazza нет, не дубликат этого вопроса (или ответа). Я не думаю, что они связаны каким-либо образом, за исключением того, что управление доступом может использовать разрешения - хотя я специально опускаю необходимость разрешений в этом вопросе. – thebjorn

ответ

0

Ну, я нашел способ, который работает перебором шаблонов, возвращенных Джанго 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'))), 
Смежные вопросы