Django Redirect If Authenticated Mixin
я хочу создать миксин для перенаправления пользователя на указанную страницу, если он уже аутентифицирован. я хочу иметь возможность использовать этот миксин в разных частях приложения без необходимости переписывать логику снова и снова.
я получаю ошибку accounts.views.view didn't return an HttpResponse object. It returned None instead., если пользователь не аутентифицирован, но все работает, если пользователь аутентифицирован. accounts это имя приложения
вот мой код в mixin.py
class RedirectIfAuthenticatedMixin:
"""
RedirectIfAuthenticatedMixin: redirect authenticated user to different page via redirect_to parameter
"""
redirect_to = None
def get(self, request):
"""
Get request handler to check if user is already authenticated
then redirect user to specified url with redirect_to
"""
if request.user.is_authenticated:
return HttpResponseRedirect(self.get_redirect_url())
# return ??? <- WHAT TO WRITE HERE TO ALLOW REQUEST TO CONTINUE EXECUTION
def get_redirect_url(self):
"""
Get the specified redirect_to url
"""
if not self.redirect_to:
raise ImproperlyConfigured('no url to redirect to. please specify a redirect url')
return str(self.redirect_to)
работает, когда я добавляю это в само представление
class RegisterView(FormView):
"""
RegisterView: form view to handle user registration
"""
def form_valid(self, form):
"""
Method to handle form submission and validation
"""
pass
# THIS WORKS,...
def get(self, request, *args, **kwargs):
if request.user.is_authenticated:
return HttpResponseRedirect(reverse_lazy('accounts:index'))
return super(RegisterView, self).get(request, *args, **kwargs)
Логика не будет оценена, если для данного представления переопределен метод get. Вероятно, лучше переопределить метод dispatch. Это также предотвратит выполнение POST, PUT, PATCH, DELETE и т.д. запросов к представлению:
class RedirectIfAuthenticatedMixin:
redirect_to = None
def get_redirect_url(self):
if not self.redirect_to:
raise ImproperlyConfigured('no url to redirect to. please specify a redirect url')
return str(self.redirect_to)
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated:
return HttpResponseRedirect(self.get_redirect_url())
return super().dispatch(request, *args, **kwargs)
Но на самом деле вы можете сделать это частным случаем UserPassesTestMixin mixin [Django-doc]:
from django.contrib.auth.mixins import UserPassesTestMixin
class RedirectIfAuthenticatedMixin(UserPassesTestMixin):
redirect_to = None
def get_redirect_url(self):
if not self.redirect_to:
raise ImproperlyConfigured('no url to redirect to. please specify a redirect url')
return str(self.redirect_to)
def handle_no_permission(self):
return HttpResponseRedirect(self.get_redirect_url())
def test_func(self):
return not self.request.user.is_authenticated
@coder-six
Я думаю, что реализация такого класса потребует от вас обработки основного запроса
в реализующем классе, т.е. реализовать метод get в дочернем классе и
затем оттуда вызывать метод get вашего класса-миксина. Чтобы упростить ситуацию, вы можете изменить метод RedirectIfAuthenticatedMixin get на redirect_if_authenticated.
Затем вам нужно будет вызвать этот метод в каждом дочернем классе, где вам нужна эта функциональность. Пример:
class RedirectIfAuthenticatedMixin:
"""
RedirectIfAuthenticatedMixin: redirect authenticated user to different page via redirect_to parameter
"""
redirect_to = None
def redirect_if_authenticated(self, request):
"""
Get request handler to check if user is already authenticated
then redirect user to specified url with redirect_to
"""
if request.user.is_authenticated:
return HttpResponseRedirect(self.get_redirect_url())
#other methods of class here ....
class RegisterView(FormView, RedirectIfAuthenticatedMixin):
"""
RegisterView: form view to handle user registration
"""
def form_valid(self, form):
"""
Method to handle form submission and validation
"""
pass
# THIS WORKS,...
def get(self, request, *args, **kwargs):
self.redirect_if_authenticated(request)
return #continue your request here if not authenticated
Но я также думаю, что использование декоратора может сделать все проще для вас.