Hans de Jong
Hans de Jong

Reputation: 2078

django return to index when there is no next= in URL

i made a login that should redirect to the previous page (with /?next=/) which seem to work, but when there is no next= it stays on the loginpage without redirecting to the index. Where do i make my mistake?

def login_user(request):
    login_form = LoginForm(request.POST or None)
    if request.POST and login_form.is_valid():
        user = login_form.login(request)
        if user:
            login(request, user)
            return HttpResponseRedirect(request.POST.get('next', reverse('index')))
            #return HttpResponseRedirect(reverse('index'))

    return render(request, 'login.html', {'login_form': login_form, 'next': request.GET.get('next', '') })

My urls.py (in my users app)

from django.conf.urls import patterns, url
from users import views
urlpatterns = patterns('',
    #Authentication urls
    url(r'^login/$', views.login_user, name='login_user'),
    url(r'^logout/$', views.logout, name='logout'),
    url(r'^register/$', views.register_user, name='register_user'),
)

my urls.py (in my characters app)

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
)

my template: (yes it isn't a beaty, bit old piece of work)

{% block content %}
<div>
    <form action="{% url 'login_user' %}" method="post" class="login">{% csrf_token %}
        <table>
        {% if login_form.non_field_errors %}
            <tr>
                <td><i style="font-size: small;">{{ login_form.non_field_errors|striptags }}</i></td>
            </tr>
        {% endif %}
        {% for field in login_form %}
            <tr>
                <td>{{ field }}</td>
            </tr>
        {% endfor %}
            <tr>
                <td style="text-align:right;" >
                    <a href="{% url 'register_user' %}">register</a>
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    <input type="submit" value="Login" />
                </td>
            </tr>
        </table>

        <input type="hidden" name="next" value="{{ next }}">
    </form>
</div>
{% endblock %}

Upvotes: 0

Views: 731

Answers (1)

knbk
knbk

Reputation: 53699

The problem is that if you don't have a next parameter specified in the GET parameters, it will be an empty string, but it will still be defined. request.POST.get('next') will never fail, but simply return an empty string. You can do the following:

def login_user(request):
    login_form = LoginForm(request.POST or None)
    if request.POST and login_form.is_valid():
        user = login_form.login(request)
        if user:
            login(request, user)
            return HttpResponseRedirect(request.POST.get('next') or reverse('index'))
            #return HttpResponseRedirect(reverse('index'))

    return render(request, 'login.html', {'login_form': login_form, 'next': request.GET.get('next', '') })

This will return the value of next, or reverse('index') if that value is empty.

Upvotes: 1

Related Questions