Правильная реализация UserPassesTestMixin или AccessMixin в представлении на основе классов - PullRequest
0 голосов
/ 07 января 2020

При использовании представлений на основе классов вы можете использовать UserPassesTestMixin следующим образом ( документы ):

from django.contrib.auth.mixins import UserPassesTestMixin

class MyView(UserPassesTestMixin, View):

    def test_func(self):
        return self.request.user.email.endswith('@example.com')

В документах также указывается:

Кроме того, вы можете установить любой из параметров AccessMixin, чтобы настроить обработку неавторизованных пользователей

Однако не приводится пример синтаксиса, как это сделать. Например, как бы установить raise_exception и permission_denied_message, чтобы аутентифицированные пользователи получали ошибку исключения, а не 403?

Это не работает, поскольку пользователям по-прежнему возвращается ошибка 403:

class MyView(UserPassesTestMixin, View):
    raise_exception = True
    permission_denied_message = 'You have been denied'


    def test_func(self):
        return self.request.user.email.endswith('@example.com')

Ответы [ 2 ]

1 голос
/ 07 января 2020

Вы должны переопределить метод handle_no_permission для обработки того, что видит пользователь, когда он не проходит тест:

class MyView(UserPassesTestMixin, View):
    def test_func(self):
        return self.request.user.email.endswith('@example.com')

    def handle_no_permission(self):
        """ Do whatever you want here if the user doesn't pass the test """
        return HttpResponse('You have been denied')
0 голосов
/ 07 января 2020

Представление на основе классов UserPassesTestMixin унаследовано от миксина AccessMixin, который имеет обозначенные параметры. Из документации повышение_экспонирования .

Если для этого атрибута установлено значение True, исключение PermissionDenied возникает, когда условия не выполняются. При значении False (по умолчанию) анонимные пользователи перенаправляются на страницу входа в систему.

Если вы установите значение True, а пользователь не прошел проверку подлинности, сервер 403 вернет статус 403. Опция permission_denied_message контролирует только сообщение, которое будет передано исключению PermissionDenied. Он не возвращает никаких сообщений пользователю (конечно, вы можете переопределить его). Немного упрощенная версия из исходного кода :

def handle_no_permission(self):
    if self.raise_exception or self.request.user.is_authenticated:
        raise PermissionDenied(self.permission_denied_message)
    return redirect_to_login(...)

Где PermissionDenied класс просто так:

class PermissionDenied(Exception):
    """The user did not have permission to do that"""
    pass
...