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.
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 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="/"
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!
I have a Django project in which I want to authenticate users against an Active Directory. Therefore, I am using the django-python3-ldap framework. I am able to sync users(./manage.py ldap_sync_users), grant superuser admin access, and login to the default Django admin page using the framework as backend. However, when I try to authenticate on my site, the user state remains AnonymousUser.
views.py
def login(request):
try:
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user, backend=django_python3_ldap)
context = {'user': user}
return render(request, 'website/home.html', context)
else:
context = {'': ''}
return render(request, 'website/login.html', context)
except:
print()
login.html
<!-- Main content -->
<section class="hero is-success is-fullheight">
<div class="hero-body">
<div class="container has-text-centered">
<div class="column is-4 is-offset-4">
<div class="box">
<figure class="avatar">
<img src="">
</figure>
<form method="post">
{% csrf_token %}
<div class="field">
<div class="control">
<input class="input is-large" type="text" placeholder="Username" autofocus="">
</div>
</div>
<div class="field">
<div class="control">
<input class="input is-large" type="password" placeholder="Password">
</div>
</div>
<div class="field">
<label class="checkbox">
<input type="checkbox">
Remember Me
</label>
</div>
<button class="button is-block is-danger is-info is-large is-fullwidth">Login</button>
{% endblock %}
</form>
</div>
</div>
</div>
</div>
</section>
imports
from django.contrib.auth import authenticate, login
import django_python3_ldap
backend
AUTHENTICATION_BACKENDS = ('django_python3_ldap.auth.LDAPBackend',)
urls.py
path('login', auth_views.login, {'template_name': 'website/login.html'}, name='login'),
I see possibly two issues the backend is not pointing to a valid backend. Also your try except is a bit dangerous please remove it. Unless you are testing never use a blank except. Use something like except Exception as e: print(e). The reason I say that is the blank except was hiding the invalid backend error.
login(request, user, backend=django_python3_ldap)
# Should be
login(request, user, backend=django_python3_ldap.auth.LDAPBackend)
I am trying to use a html form from the internet with Django. However, after watching crazy amount of videos on youtube and reading through https://docs.djangoproject.com/en/1.10/topics/forms/ , I can't manage to make it work. When I click the submit button, Chrome tells me the "The form has submitted", but nothing else happens. It should log the user in and redirects to the index page.
registration_form.html
<div class="panel panel-info mt10 br-n bg-gradient-1 mw500 mauto">
<form id="contact" method="post" action="{% url 'feed:connection' %}">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="panel-body text-center p50 text-center">
<div class="section">
<p class="text-uppercase text-white ls100 fw700">Username</p>
{{ form.username.errors }}
<label for="username" class="field prepend-icon">
<input id="username" type="text" name="username" placeholder="Enter username" class="gui-input">
</label>
</div>
<div class="section">
<p class="text-uppercase text-white ls100 fw700">Password</p>
{{ form.password.errors }}
<label for="password" class="field prepend-icon">
<input id="password" type="password" name="password" placeholder="Enter password" class="gui-input">
</label>
</div>
<div class="panel-footer clearfix p10 ph15">
<button type="submit" class="button btn-primary mr10 pull-right text-uppercase text-white ls100 fw700">Sign In</button>
<!--<label class="switch ib switch-primary pull-left input-align mt10">
<input id="remember" type="checkbox" name="remember" checked="">
<label for="remember" data-on="YES" data-off="NO"></label> <span>Remember me</span>
</label> -->
</div>
<div class="section text-left pt20 pb10">Forget password?
<p><span class="text-white">Haven't yet registration? Sign up here</span></p>
</div>
<div class="section row">
<div class="col-md-6">Facebook</div>
<div class="col-md-6">Google +</div>
</div>
</div>
</form>
</div>
views.py
from django.views.generic.base import TemplateView
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from django.views.generic import View
from .forms import LoginForm
# Pour faire afficher la page index
class IndexView(TemplateView):
template_name = 'feed/index.html'
# Pour se logger
class UserFormView(View):
form_class = LoginForm
template_name = 'feed/registration_form.html'
# display blank form
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
# process form data
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
# cleaned (normalized) data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.username = username
user.save()
# returns User objects if credentials are correct
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('feed:index')
return render(request, self.template_name, {'form': form})
urls.py
from django.conf.urls import url, include
from . import views
app_name = "feed"
urlpatterns = [
# /feed/
url(r'^$', views.IndexView.as_view(), name='index'),
# /register/
url(r'^connection/$', views.UserFormView.as_view(), name='connection'),
]
forms.py
from django import forms
class LoginForm(forms.Form):
user = forms.CharField(max_length=100)
password = forms.CharField(widget=forms.PasswordInput, min_length=8)
What is wrong with the code? Thank you for your time.