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

Но я также думаю, что использование декоратора может сделать все проще для вас.

Вернуться на верх