简体   繁体   中英

Django POST request redirects to empty url after submitting form

I have a login form with POST method and when I submit the login data, it goes straight to the empty url and doesn't execute the login method in views.py. Ideally, after I submit the form in www.url.com/login via submit button, it should return a HttpResponse but instead, it takes me to www.url.com/

I am new to Django, I'd appreciate it if you could look into it. Thanks!

home.html

    <center><h1>Welcome to my website</h1>
    <form method='POST'> {% csrf_token %}
    {{ form }}
    <button type='submit' class='btn btn-default'>Submit</button>
    </form>
    </center>

urls.py

from django.contrib import admin
from django.urls import path

from .views import home, login

urlpatterns = [
    path('', home),
    path('login/', login),
    path('admin/', admin.site.urls),
]

forms.py

from django import forms

class LoginForm(forms.Form):
    username = forms.CharField(widget=forms.TextInput(attrs={"class":"form-control", "placeholder":"Your username"}))
    password = forms.CharField(widget=forms.PasswordInput(attrs={"class":"form-control", "placeholder":"Your password"}))

views.py

from django.contrib.auth import authenticate, login
from django.http import HttpResponse
from django.shortcuts import render

from .forms import LoginForm

def home(request):
    context={
        "form": "Test"
    }
    return render(request, "home.html", context)

def login(request):
    login_form = LoginForm(request.POST or None)
    context={
        "form": login_form
    }
    if login_form.is_valid():
        username = login_form.cleaned_data.get('username')
        password = login_form.cleaned_data.get('password')
        user = authenticate(request, username=username, password=password)
        if user is not None:
            #request.user.is_authenticated()
            login(request, user)
            return HttpResponse("You are now logged in")
        else:
            return HttpResponse('Error')
    return render(request, "home.html", context)

First, you should set an attribute action in the form which set a url to send.

Second, a url value in action must be clear. It's not a matter of Django but HTML. I'd like to recommend you to use absolute path . If you use relative path , a slash string would be added whenever you send a request.

<form action="/login/" method='POST'>
  {% csrf_token %}
  {{ form }}
  <button type='submit' class='btn btn-default'>Submit</button>
</form>

This is because your form doesn't contain action , ie where should the POST call be made with the user credentials.

Try following change in home.html :

<center><h1>Welcome to my website</h1>
<form action="" method='POST'> {% csrf_token %}
{{ form }}
<button type='submit' class='btn btn-default'>Submit</button>
</form>
</center>

Following the answers before, it would be a good practice to use named patterns instead of fixed urls.

# urls
...
path('login/', login, name='login'),
...

# template
<form action="{% url 'login' %}" method='POST'>

So if you change for example

login/

for

accounts/login/

You don't have to change the template as well.

urlpatterns = [
    re_path('^$', home_page),
    re_path('^admin/', admin.site.urls),
    re_path('^register/$', register_page, name='register'),
    re_path('^login/$', login_page, name='login'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

I solved this by adding ^$ to the beginning and end of the patterns.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM