Создание пользовательских Исключений, на которые реагирует Django

Для моего сайта я создал абстрактную Модель, которая реализует полномочия чтения образцового уровня. Та часть системы завершается и работает правильно. Один из методов, которые представляет permissioned модель, is_safe(user) который может вручную протестировать, если пользователю разрешают просмотреть ту модель или нет.

То, что я хотел бы сделать, добавляет метод к эффекту continue_if_safe который можно назвать на любом образцовом экземпляре, и вместо того, чтобы возвратить булево значение как is_safe это сначала протестировало бы, если модель может быть просмотрена или нет, то в случае Лжи, это перенаправило бы пользователя, или к странице входа в систему, если они не уже зарегистрированы или возвращают 403 ошибки, если они зарегистрированы.

Идеальное использование:

model = get_object_or_404(Model, slug=slug)
model.continue_if_safe(request.user)
# ... remainder of code to be run if it's safe down here ...

Я посмотрел на то, как get_object_or_404 работает, и он бросает Http404 ошибка, которая, кажется, имеет смысл. Однако проблема состоит в том, что, кажется, нет эквивалентного перенаправления или 403 ошибок. Что лучший способ состоит в том, чтобы пойти об этом?

(нерабочий) continue_if_safe метод:

def continue_if_safe(self, user):

    if not self.is_safe(user):
        if user.is_authenticated():
            raise HttpResponseForbidden()
        else:
            raise HttpResponseRedirect('/account/')

    return

Редактирование - решение

Код для конечного решения, в случае, если другие "накопители" нуждаются в некоторой помощи с этим:

В абстрактной модели:

def continue_if_safe(self, user):
    if not self.is_safe(user):
        raise PermissionDenied()
    return

Представления пойманы промежуточным программным обеспечением:

class PermissionDeniedToLoginMiddleware(object):
    def process_exception(self, request, exception):
        if type(exception) == PermissionDenied:
            if not request.user.is_authenticated():
                return HttpResponseRedirect('/account/?next=' + request.path)
        return None

Использование в представлении (очень короткий и сладкий):

model = get_object_or_404(Model, slug=slug)
model.continue_if_safe(request.user)
15
задан T. Stone 19 February 2010 в 20:14
поделиться

2 ответа

Для запрещенной (403) ошибки вы можете поднять исключение PermissionDenied (из django.core.exceptions).

Что касается поведения перенаправления, нет встроенного способа справиться с этим так, как вы описали в своем вопросе. Вы можете написать пользовательское промежуточное ПО, которое будет ловить исключение и перенаправлять в process_exception.

10
ответ дан 1 December 2019 в 04:00
поделиться

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

Ваш код будет выглядеть примерно так:

@safety_check:
def some_view(request):
    #Do Stuff
1
ответ дан 1 December 2019 в 04:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: