Django: Применение разрешений в диспетчере URL?

В моем приложении Django у меня есть определенные разрешения, которые нужны пользователям для доступа к определенным представлениям (используя django.contrib.auth). Это отлично работает, используя декоратор @permission_required в моих функциях просмотра.

Однако некоторые из моих URL-адресов разрешаются в представления, которые я не писал, например, встроенный django.contrib.auth.views.password_change, как в следующем urls.py:

urlpatterns = patterns(
 (r'^$', "users.views.index"),
 (r'^password_change/$', 'django.contrib.auth.views.password_change'))

В данном случае мне некуда применить декоратор @permission_required — или нет? Есть ли способ применить ограничение разрешений на уровне диспетчера URL?


person kdt    schedule 11.08.2010    source источник


Ответы (4)


Можно импортировать требуемую функцию входа в систему и применить ее к общему представлению:

from django.contrib.auth.decorators import login_required
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('',
    (r'^foo/$', login_required(direct_to_template), {'template': 'foo_index.html'}),
    )

как указано здесь.

person Hoff    schedule 11.08.2010
comment
Как бы вы использовали permission_required таким же образом? В частности, как бы вы передали ему аргумент имени разрешения? - person Manoj Govindan; 12.08.2010
comment
@Manoj: ознакомьтесь с этим разделом документации: docs.djangoproject.com/en/dev/topics/auth/ идея состоит в том, чтобы написать тонкую оболочку (с декоратором permission_required) вокруг общего представления и указать ваш urlconf на эту оболочку... - person Hoff; 13.08.2010
comment
Это то, что я сделал в своем ответе. Просто хотел узнать, есть ли другой способ сделать это. Спасибо. - person Manoj Govindan; 13.08.2010
comment
Мне нужен настраиваемый декоратор, как я могу создать настраиваемую функцию проверки разрешений, чтобы обернуть функцию просмотра, спасибо. - person Alston; 04.10.2016
comment
@stallman просто напишите свой собственный декоратор, импортируйте его и используйте вместо login_required. Декораторы - это просто функция, и ее можно использовать как одну... - person Hoff; 06.10.2016

Декоратор — это модное слово для обозначения функции, которая является оболочкой другой функции. login_required — это функция-оболочка для представления, а permission_required создает оболочку для вашего представления. Другими словами, login_required сам является декоратором, а permission_required(perm) создает декоратор.

from django.conf.urls import url
from django.contrib.auth.decorators import login_required, permission_required

urlpatterns = [
    url(r'^public/', myview),

    url(r'^users_only/', 
        login_required(myview)),

    url(r'^users_with_perms/',
        permission_required('myapp.view_mymodel', login_url='login')(myview)),

    url(r'^login_page/', myloginview, name='login'),
]
person jozxyqk    schedule 15.07.2015
comment
Ты самый лучший! Этот ответ более понятен, чем избранный - person Julio Marins; 25.03.2016

Один из подходов состоит в том, чтобы обернуть представления, которые вы не написали.

from django.contrib.auth.views import password_change

@permission_required('my_perm')
def wrapper(*args, **kwargs):
    return password_change(*args, **kwargs)

#URLs
urlpatterns = patterns(
  (r'^$', "users.views.index"),
  (r'^password_change/$', 'wrapper'))
person Manoj Govindan    schedule 11.08.2010

У меня есть небольшой лайфхак о преобразователе URL-адресов Django, вы можете применить декоратор на уровне отправки URL-адресов:

from django_url_decr import url_decr
from django.contrib.auth.decorators import login_required

urlpatterns = patterns(''
                       url_decr(r'^users/',
                                include('users.urls'),
                                decr=login_required))
person socrates    schedule 02.11.2014