djangomixins

Why LoginPemissionMixin redirects to the wrong url


I make my project with Django. I want to let only logged user to access URL. When my class uses LoginRequiredMixin to redirect to login view, after successful login it redirects to URL "main".

views.py

class LoginView(FormView):
    form_class = LoginForm
    template_name = "tavern_app/login.html"
    success_url = reverse_lazy("main")

    def form_valid(self, form):
        user = form.user
        login(self.request, user)
        return super().form_valid(form)


class CreateSessionBaseView(LoginRequiredMixin, View):
    login_url = '/log-in/'

    def get(self, request):

        return render(request, "tavern_app/create_session_base.html")

urls.py

    path("log-in/", LoginView.as_view(), name="login"),
    path("create-session/", CreateSessionBaseView.as_view(), name="create-session-base"),

at this moment, when I enter CreateSessionBaseView as not logged user it redirects to log-in with URL:

http://127.0.0.1:8000/log-in/?next=/create-session/

But after successful login it redirects to "main" as it's defined in LoginView.

I've tried to deal with it with redirect_field_name:

class CreateSessionBaseView(LoginRequiredMixin, View):
    login_url = 'login'
    redirect_field_name = 'redirect_to'

    def get(self, request):

        return render(request, "tavern_app/create_session_base.html")

it changes URL to

http://127.0.0.1:8000/log-in/?redirect_to=/create-session/

but it seems like success_url from LoginView is still winning.

How to redirect it back to my "create-session-base" page. I still want my "login" view to redirect to "main" in other cases.


Solution

  • OK. So i resolved it by adding this to Login view :

    redirect_to = self.request.GET.get('next', None)
            if redirect_to:
                return HttpResponseRedirect(redirect_to)
            else:
                return HttpResponseRedirect(reverse_lazy("main"))
    

    Now it looks like this

    class LoginView(FormView):
        form_class = LoginForm
        template_name = "tavern_app/login.html"
        success_url = reverse_lazy("main")
    
        def form_valid(self, form):
            user = form.user
            login(self.request, user)
    
            redirect_to = self.request.GET.get('next', None)
            if redirect_to:
                return HttpResponseRedirect(redirect_to)
            else:
                return HttpResponseRedirect(reverse_lazy("main"))
    
            return super().form_valid(form)
    
    
    class CreateSessionBaseView(LoginRequiredMixin, View):
        login_url = 'login'
    
        def get(self, request):
    
            return render(request, "tavern_app/create_session_base.html")
    

    Now if URL address has ?next it redirects to right view. Like here:

    http://127.0.0.1:8000/log-in/?next=/create-session/
    

    In other cases it redirects to "main" like here:

    http://127.0.0.1:8000/log-in/