Django выполняет действие непосредственно перед вызовом login_required?

В django я хочу выполнить определенное действие непосредственно перед вызовом login_required() для представления. Один хак или простой выход - просто указать этот URL-адрес на представление, где вход в систему не требуется, и выполнить это конкретное действие (действие: установка некоторых вещей в request.session), а затем перенаправить обратно в это основное представление, где требуется вход в систему. .

Как мне это сделать, если в django есть возможность удовлетворить такие вещи?

Есть ли лучший или более простой способ, чем написать собственный декоратор для этого?


person zubinmehta    schedule 28.12.2011    source источник
comment
Ваш взлом не гарантирует, что ваше действие будет выполнено; пользователи, которые знают URL-адрес представления с login_required, могут легко обойти другое представление. К сожалению, я не знаю решения вашей проблемы.   -  person Jesse Webb    schedule 29.12.2011


Ответы (4)


Декоратор — лучший способ, потому что он упрощает понимание кода, а из соображений безопасности пользователь может блокировать перенаправления, поэтому вам нужно подумать, как этого избежать.

Эта статья кажется полезной Как создать цепочку декораторов функций?, потому что я думаю, что вам нужно передайте переменную запроса, а также поместите свой декоратор для обработки проверки в первую очередь.

person Dracontis    schedule 28.12.2011

Вместо этого просто используйте декоратор user_passes_test и делайте свои собственные вещи, прежде чем вручную проверять, что они аутентифицированы. См.: https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.user_passes_test

person Chris Pratt    schedule 28.12.2011
comment
+1: декоратор login_required фактически использует user_passes_test внутри, так что это, вероятно, сработает. Я по-прежнему считаю, что промежуточное программное обеспечение является правильным подходом, основываясь на примере ОП. - person elo80ka; 29.12.2011
comment
Промежуточное ПО, скорее всего, ведет базуку в поножовщину. user_passes_test просто заменит декоратор login_required, который он уже использует, и предоставит ему доступ к сеансу, чтобы добавить все необходимые дополнительные переменные. - person Chris Pratt; 29.12.2011

Ваш вопрос не дает подробностей, но, судя по вашему примеру (установка некоторых переменных запроса), похоже, вам нужно ПО промежуточного слоя запроса. Взгляните на встроенный django.contrib.auth.middleware.AuthenticationMiddleware для примера:

class AuthenticationMiddleware(object):
    def process_request(self, request):
        assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."

        request.user = SimpleLazyObject(lambda: get_user(request))

Вам нужно будет определить класс с process_request метод (как показано выше). Метод process_request будет вызываться для каждого запроса и передавать экземпляр запроса. В этом методе вы можете проверить request.user и аутентифицирован ли пользователь, а также установить любые переменные, которые вы хотите для текущего запроса.

person elo80ka    schedule 29.12.2011

Написание собственного декоратора — лучший способ приблизиться к этому. Везде, где у вас есть @login_required, просто добавьте свой собственный декоратор в дополнение к декоратору login_required.

Или вы можете вызвать функцию login_required из своего декоратора.

person Jordan    schedule 28.12.2011
comment
Не нужно заменять декоратор Django, просто добавьте свой декоратор в нужное место, они будут вызываться один за другим. - person demalexx; 29.12.2011
comment
Я не был ясен. Я хотел сказать, что вы добавите оба, поэтому я отредактирую свой ответ, чтобы сделать его более понятным. - person Jordan; 29.12.2011