[Django]-Django redirect after login not working "next" not posting?

43๐Ÿ‘

โœ…

Your code is fine, the only problem is that in the form you are passing the next attribute as a post because the method is post. In the views you try to get the next parameter within the get dictionary which is obvious not there.

You have to declare the html form action like this in order to your views work.

{% if next %}
<form action="/login/?next={{next}}" method="post" >
{%else%}
<form action="/login/" method="post" >
{% endif %}
        {% csrf_token %}
        username:
        <input type="text" name="username" value="{{ username }}" /><br />
        password:
        <input type="password" name="password" value="" /><br />

        <input type="submit" value="Log In"/>

        {% debug %}
    </form>

There, if there is a next variable then you include in the url for retrieve it as a get parameter. If not, the form doesnโ€™t include it.

This is the best approach, but you may also fix this in your views by requesting the next from the POST dictionary like this:

return HttpResponseRedirect(request.POST.get('next'))

Note that this will only work if the template account_login has a variable called next. You should generate it in the views and pass it to the template when you render it.

Normally, in the template you would do something like this:

# this would be hardcoded
next = '/issueapp/1628/view/22'
# you may add some logic to generate it as you need.

and then you do:

return render_to_response(
    'account_login.html',
    {
    'state':state,
    'username': username,
    'next':next
    },
    context_instance=RequestContext(request)
)

Hope this helps!

๐Ÿ‘คPaulo Bu

6๐Ÿ‘

In short

I would define in your view function next_page = request.GET['next'] and then redirect to it by return HttpResponseRedirect(next_page) so you never need to change templates; just set @login_required and you are fine.

As example:

User A tries to access โ€“ while not logged in โ€“ https://www.domain.tld/account/. Django redirects him because @login_required is set to the defined LOGIN_URL in your settings.py. The method UserLogin now tries to GET the next parameter and redirects to it if user A logs in successfully.

settings.py

LOGIN_URL = '/login/'

urls.py

url(r'^account/', account, name='account'),
url(r'^login/$', UserLogin, name='login'),

views.py

@login_required
def account(request):
    return HttpResponseRedirect("https://www.domain.tld/example-redirect/")

def UserLogin(request):
    next_page = request.GET['next']
    if request.user.is_authenticated():
        return HttpResponseRedirect(next_page)
    else:
        if request.method == 'POST':
            if form.is_valid():
                username = form.cleaned_data['username']
                password = form.cleaned_data['password']
                user = authenticate(email=username, password=password)
                if user is not None and user.is_active:
                    login(request, user)
                    return HttpResponseRedirect(next_page)
                else:
                    error_msg = 'There was an error!'
                    return render(request, "login", {'form': form, 'error_msg': error_msg})
            else:
                error_msg = "There was an error!"
                return render(request, "login", {'form':form, 'error_msg':error_msg})
        else:
            form = UserLoginForm()
            return render(request, "login", {'form': form})
๐Ÿ‘คrwx

5๐Ÿ‘

Just put

<form action="" method="post" >

Empty action โ€˜what ever current complete url isโ€˜

๐Ÿ‘คRizwan Mumtaz

3๐Ÿ‘

If you want to be more generic, you could just do something like this, which passes any of the GET parameters along when the form is posted:

<form action="/path-to-whatever/{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" method="post">
๐Ÿ‘คseddonym

1๐Ÿ‘

Instead of assigning next in your view & passing it to template, isnโ€™t it cleaner to use ?next={{request.path}} in your template. (Remember to enable django.core.context_processors.request in settings.py, which is usually enabled in by default in django 1.6)

Here is the link tells about the same

https://docs.djangoproject.com/en/1.6/topics/auth/default/#the-raw-way

<form action="/login/?next={{request.path}}" method="post" >

is the code required.

Note:

You can get the current url with request.path from view also.

Thanks to buffer. I have just copy and pasted your comment after trying it myself in my own code.

๐Ÿ‘คAjeeb.K.P

Leave a comment