I have a login modal in base.html. on clicking the login button modal gets open. I want that when the form has submitted the action='login' should call the login function of views.py but when I try to submit, it redirects the page to the login page which does not exist ('http://127.0.0.1:8000/login'). I want to know how can I call login function of views from modal, if I'm not wrong then action='' attribute calls the function and not the page. I tried removing the path of login from urls.py.
base.html
<div class="modal fade" id="modalLoginForm">
<div class="modal-dialog" role="document">
<div class="modal-content">
<!-- Default form login -->
<form class="text-center border border-light" action="login" method="post" autocomplete="off">
{% csrf_token %}
<!-- Email -->
<input type="text" name="username" class="form-control mb-4" placeholder="E-mail" required>
<!-- Password -->
<input type="password" name="password" class="form-control mb-4" placeholder="Password" required>
<div class="d-flex justify-content-around">
<div>
<!-- Remember me -->
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="defaultLoginFormRemember" name="remember_me">
<label class="custom-control-label" for="defaultLoginFormRemember">Remember me</label>
</div>
</div>
<div>
<!-- Forgot password -->
Forgot password?
</div>
</div>
<!-- Sign in button -->
<input class="btn btn-info btn-block my-3" type="submit" value="Sign in">
</form>
<!-- Default form login -->
</div>
</div>
</div>
views.py
def login(request):
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect('/')
else:
messages.info(request, 'invalid credentials')
return redirect('index')
else:
return render(request, 'index.html')
app urls.py
urlpatterns = [
path('', views.login, name='login'),
path('register',views.register, name='register'),
path('logout', views.logout, name='logout')
]
project urls.py
urlpatterns = [
path('', include('camroid_app.urls')),
path('accounts/', include('accounts_app.urls')),
path('admin/', admin.site.urls),
]
how can i call login() of views from <form action='login'>
as it is raising error: The current path, login, didn't match any of these.
how can i call function of views directly from <form action='login'>
try:
action="{% url 'login' %}"
or
action="/"
Related
I have tried to add a book in to the database using an HTML form. After the submission, the page redirect to a page where all the books are listed .Then whenever I refresh the page , the data is became duplicated. How do I resolve this problem?
urls.py
from django.urls import path
from . import views
app_name='library'
urlpatterns =[
path('', views.home, name='home'),
path('book/',views.book,name='book'),
path('book_details/<int:book_id>',views.book_details,name='book_details'),
path('book_edit/<int:book_id>',views.book_edit,name='book_edit'),
path('book_delete/<int:book_id>',views.book_delete,name='book_delete'),
path('update/<int:book_id>',views.update,name='update'),
path('author/',views.author_view,name='author_view'),
path('addbook/',views.add_book,name='add_book'),
path('books/',views.add_submit,name='add_submit'),
]
views.py
def add_submit(request):
if request.method =='POST':
title=request.POST.get('t_title')
print(title)
author_name=request.POST.get('a_author')
author, created=Author.objects.get_or_create(Name=author_name)
summary=request.POST.get('s_summary')
date=request.POST.get('d_date')
book=Book(Title=title,Author=author,Summary=summary,Published_date=date)
book.save()
books=Book.objects.all()
return render(request,'books.html',{'books':books})
Template file:
<form action="{% url 'library:add_submit' %}" method="POST">
{% csrf_token %}
<div class="form-outline mb-4">
<input type="text" id="bname" name="t_title" class="form-control" />
<label class="form-label" for="bname">Title</label>
</div>
<div class="form-outline mb-4">
<input type="text" id="bauthor" name="a_author" class="form-control" />
<label class="form-label" for="bauthor">Author</label>
</div>
<div class="form-outline mb-4">
<textarea rows="5" cols="33" id="bsummary" name="s_summary" class="form-control"></textarea>
<label class="form-label" for="bsummary">Summary</label>
</div>
<div class="form-outline mb-4">
<input type="date" placeholder="" id="pdate" name="d_date" class="form-control" />
<label class="form-label" for="pdate">Published_Date</label>
</div>
<!-- Submit button -->
<button type="submit" class="btn btn-primary btn-block">SUBMIT</button>
</form>
This is most common problem, the thing is that after dealing with POST data you should always return an HttpResponseRedirect, the tip is not specific to Django, but it's a good web practice in general so:
urls.py:
urlpatterns =[
...
path("success/", views.success, name="success"
]
views.py:
def add_submit(request):
if request.method =='POST':
title=request.POST.get('t_title')
print(title)
author_name=request.POST.get('a_author')
author, created=Author.objects.get_or_create(Name=author_name)
summary=request.POST.get('s_summary')
date=request.POST.get('d_date')
book=Book(Title=title,Author=author,Summary=summary,Published_date=date)
book.save()
return redirect("library:success")
else:
books=Book.objects.all()
return render(request,'books.html',{'books':books})
def success(request):
return render("success.html")
success.html
<h2> The form has been successfully submitted.</h2>
Go back to form
I builded a login form in Django. Now I have a problem with the routing.
When I select the login button, the form doesn`t send the correct awnser.
I think the form in the frontend cannot gets the correct awnser from the
view.py file. So it will send no awnser and the login process canot work and
the form is a simple static html form.
I hope you can help me.
HTML:
<form class="windowlogscreen-content" method="POST">
{% csrf_token %}
<input type="text" placeholder="account" name="username">
<br>
<input type="password" placeholder="password" name="password">
<br>
<button style="margin: 20px;" type="submit">join</button>
</div>
</div>
</form>
views.py
def loginuser(request):
if request.method == "POST":
username = request.POST['accountName']
password = request.POST['accountPassword']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return views.homepage
else:
return redirect('start')
else:
return render(request, 'start', {})
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', start),
path('homepage/', include('homepage.urls'))
]
homepage urls.py
urlpatterns = [
path('login/', views.login, name="login"),
path('register/', views.register, name="register"),
path('', views.homepage, name="homepage"),
path('account/', views.account, name="account")
]
def login(request):
if request.method = 'POST':
username = request.POST['username']
password = request.method = POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect(#User to the dashboard!)
else:
message.info(request, "invalid credentials")
return redirect('login')
else:
return render(request, 'login.html')
Login.html:
<form method="POST" action="{% url 'login' %}">
{% csrf_token %}
<div class="form-group">
<label class="text-primary text-dark font-weight-bold">Enter Username</label>
<input type="text" class="form-control" name="username" placeholder="Enter Username">
</div>
<br>
<div class="form-group">
<label class="text-primary text-dark font-weight-bold">Enter Password</label>
<input type="password" class="form-control" name="password" placeholder="Enter Password">
</div>
<br>
<button type="submit" class="btn btn-primary btn-lg">Log in</button>
</form>
Docs
I am currently learning Django,I connected my register FORM with my views.py, and wrote a little backend code, the problem, is that it links successfully with my .html file, and the POST elements are registering, but as I try to make a verification, (if POST_element < 10), it does nothing.
Edit: The Post elements are recognised by my backend, I test it out with a print(username) statement and it works fine.
Here is a part of my HTML Register FORM:
<div class="limiter">
<div class="container-login100" style="background:black;">
<div class="wrap-login100">
<form action="{% url 'register' %}" method="POST" class="login100-form validate-form">
{% csrf_token %}
<span class="login100-form-logo">
<i class="zmdi zmdi-landscape"></i>
</span>
<span class="login100-form-title p-b-34 p-t-27">
Register
</span>
<div class="wrap-input100 validate-input" data-validate = "Enter username">
<input class="input100" type="text" name="username" placeholder="Username">
<span class="focus-input100" data-placeholder=""></span>
</div>
Here is a part of my views.py that manages register:
def register(request):
if request.method=="POST":
username = request.POST["username"]
password = request.POST["pass"]
password_confirm = request.POST["pass-confirm"]
email = request.POST["mail"]
if len(username) < 7:
messages.error(request,"Username must be more than 10 char.") #Don't get any error
else:
messages.success(request,"Success")
return render(request, 'users/register.html')
Here is my urls.py:
urlpatterns = [
path('', views.register, name='register'),
path('login/', views.login, name='login')
]
An Excerpt from the django-doc about POST request.
You should always return an HttpResponseRedirect after successfully dealing with POST data. This tip isn’t specific to Django; it’s good web development practice in general.
You haven't return any response in POST request, and the messages framework whether any messages consists of error,success,etc. will send messages to next redirected page, so that's why you are not able to see the message, and your condition is working.
check the below code:
Html code:
<div class="limiter">
<div class="container-login100" style="background:black;">
<div class="wrap-login100">
<form class="login100-form validate-form" method='POST' action="{% url 'users:register' %}" >
{% csrf_token %}
<span class="login100-form-logo">
<i class="zmdi zmdi-landscape"></i>
</span>
<span class="login100-form-title p-b-34 p-t-27">
Register
</span>
<div class="wrap-input100 validate-input" data-validate = "Enter username">
<input class="input100" type="text" name="username" placeholder="Username" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Enter password">
<input class="input100" type="password" name="pass" placeholder="Password" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Confirm password">
<input class="input100" type="password" name="pass-confirm" placeholder="Confirm Password" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Enter Email">
<input class="input100" type="email" name="mail" placeholder="E-Mail" required>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="container-login100-form-btn">
<button class="login100-form-btn">
Register
</button>
</div>
<div class="text-center p-t-90">
<a class="txt1" href="login">
Already registered?
</a>
</div>
</form>
</div>
</div>
</div>
Set following style at the top of page in <style> tag, i.e. inline style:
<style>
.green{
color:green;
font-size:1.3rem;
}
.red{
color:red;
font-size:1.3rem;
}
</style>
urls.py
app_name='users'
urlpatterns = [
path('', views.register, name='register'),
path('login/', views.login, name='login')
]
Note: Giving app_name is a good practice,works like template namespacing while giving urls.
views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.contrib import messages
from django.urls import reverse
def register(request):
if request.method == "POST":
username = request.POST["username"]
password = request.POST["pass"]
password_confirm = request.POST["pass-confirm"]
email = request.POST["mail"]
# Here everying exist.
print("UserName : ", username)
print('Email : ', email)
print('Password : ', password)
print('Password Confirm : ', password_confirm)
if len(username) < 7:
# Here error exist.
print('Username must be more than 10 char.')
messages.error(
request, "Username must be more than 10 char.", 'red')
return HttpResponseRedirect(reverse('users:register'))
else:
messages.success(request, "Success! form submitted.", 'green')
return HttpResponseRedirect(reverse('users:register'))
return render(request, 'users/register.html')
Note: You can also do password hashing through make_password which is from django.contrib.auth.hashers import make_password.
I've created a login page as a homepage and only by adding manually in Django administration can create a user. I didn't create a registration form and message error else statement in home viwes.py is working on the admin panel. If I login by user, I get CSRF token error
homepage
views.py
from django.shortcuts import redirect, render
from loginapp.models import Register
from django.contrib import messages
from django.contrib.auth import authenticate, login , logout
def home(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request,username=username, password=password)
if user is not None:
login(request, user)
return render(request, "home.html")
else:
messages.error(request, "Bad Creds!!")
return redirect('/')
return render(request, "home.html")
login page views.py
def index(request):
return render(request, "index.html")
login page name as index.html
<form id="stripe-login" method="POST" action="{% url 'home' %}">
{% csrf_token %}
<div class="trick" style="padding-bottom: 10px;">
<input type="text" name="username" required>
<label for="email">Username</label>
</div>
<div class=" trick" style="padding-bottom:10px;">
<input type="password" name="password" required>
<label for="password">Password</label>
</div>
<div class="field" style="padding-bottom:10px; padding-top: 10px;">
<input type="submit" name="submit" value="Continue">
</div>
<div class="reset-pass" style="padding-top: 20px;">
Forgot your password?
</div>
<div class="footer-link text-light" style="padding-top:10px;">
<span>
Don't have an account?
<a href="{% url 'signup' %}">
Request for a new account
</a>
</span>
</div>
</form>
for creating user you must use
User.objects.create_user() method
Ex: User.objects.create_user(username=username,email=email,password=password)
I have a very common problem - after login I want to redirect to the page where login was called. I can describe situation exactly like here: Django: Redirect to previous page after login
There are 2 options where you can log in - from the home page (which is defined in base.html) and from bokeh.html (other views inherit from bokeh)
my base.html and bokeh.html have the same block to redirect to login. Difference is, that login called from home page should return to home page and from other page should return to page where was called.
<li class="nav-item">
<a class="nav-link" href="{% url 'login' %}">Login</a>
</li>
my login.html
<form method="POST">
{% csrf_token %}
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter Username" name="username" required>
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="Enter Password" name="password" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn-dark">Login</button>
</div>
</form>
and views.py
def login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
return redirect('home')
else:
messages.info(request,'Invalid credentials')
return redirect('login')
else:
return render(request,'login.html')
I was trying to add next to my form in login.html but it didn't work. While accessing to login from page other than home page it was like: localhost:8000/login?next=/bokeh/ and after submiting form I was still on login but URL changed to localhost:8000/login?next=. I know it's pretty hard to explain but I will add another information in need.
First, change the template to include the urlencoded next parameter to the login url:
<li class="nav-item">
<a class="nav-link" href="{% url 'login' %}?next={{ request.path |urlencode }}">Login</a>
</li>
Second, your login template needs to preserve the value of next:
<form method="POST">
<input type="hidden" name="next" value=""{{ next }}">
{% csrf_token %}
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter Username" name="username" required>
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="Enter Password" name="password" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn-dark">Login</button>
</div>
</form>
Third, your login view should retrieve the URL parameter and pass it to the template:
from django.conf import settings
def login(request):
if request.method == 'GET':
next = request.GET.get('next', settings.LOGIN_REDIRECT_URL)
return render(request, 'login.html', {'next': next})
if request.method == 'POST':
next = request.POST['next']
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
return redirect(next)
else:
messages.info(request,'Invalid credentials')
return redirect('login')
Finally, you should consider using the Django Authentication Views instead of writing your own login views!