Im trying to write my own django login page. Eveything is ok up to the point where I try to login and I just get redirected back to the main login view.
TEMPLATE
{% extends "bdayremind-maininput.html" %}
{% block main %}
<form class="form-horizontal" name="LoginForm" action="/login/" method="post">
{% csrf_token %}
{% if next %}
<input type="hidden" name="next" value="{{ next }}" />
{% endif %}
<div class="control-group">
<label class="control-label" for="username">Username</label>
<div class="controls">
<input type="text" id="username" value="{{username}}" placeholder="Username">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">Password</label>
<div class="controls">
<input type="password" name="password" id="password" placeholder="Password">
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">Login</button>
</div>
</div>
</form>
{% endblock %}
URLS
urlpatterns = patterns('',
url(r'^bdayremind_maininput/$', 'birthdayreminder.views.main'),
# login / logout
(r'^login/$', 'birthdayreminder.views.login_user'),
#(r'^logout/$', logout_page),
)
VIEWS
import datetime
from django.http import *
from django.shortcuts import render_to_response
from django.template import RequestContext
from birthdayreminder.models import *
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login
def login_user(request):
username = password = ''
if request.POST:
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect('birthdayreminder.views.main')
return render_to_response('login.html',{'username': username}, context_instance=RequestContext(request))
#login_required(login_url='/login/')
def main(request):
........
Any Ideas ?
You forgot to add redirect to the desired page after login.
Related
<form action="login" method="post" >
{% csrf_token %}
<div class="form-group mb-3">
<label class="label" for="name">username</label>
<input type="text" id="username" class="form-control" required>
</div>
<div class="form-group mb-3">
<label class="label" for="password">password</label>
<input type="password" id="password" class="form-control" required>
</div>
<div class="form-group">
<input type="submit" action="login">
</div>
<div class="form-group d-md-flex">
<div class="w-50 text-left">
<label class="checkbox-wrap checkbox-primary mb-0">Remember Me
<input type="checkbox" checked>
<span class="checkmark"></span>
</label>
</div>
<div class="w-50 text-md-right">
Forgot Password
</div>
This is the form.
def login(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 redirect("dashboard")
else:
messages.info(request, "User doesn't exist. Contact the teacher!")
return redirect("index")
else:
return render(request, "login.html")
This is the views function.
from django.shortcuts import render, redirect
from django.contrib.auth.models import User, auth
from django.contrib import messages
from django.contrib.auth import authenticate, login
Those are the imports.
But this doesn't redirect user who has already registered, to the page specified. Not a problem of urls or the csrf_token. I think the problem is in the sending data part because the else function triggers and shows the massege user doesn't exist..... Please help.
I have created a user and given him all the required data, but I cannot log into the page, I sure the email and password correct , but it gives me error in the information entered.
template:
<form action="" method="post" class="border rounded overflow-hidden p-5">
{% csrf_token %}
<h4 class="text-center py-3 title">Login </h4>
{% for message in messages %}
<div class="btn btn-sm btn-dark col-6" role="alert">
<h3 class="text-center"> {{ message }}</h3>
</div>
{% endfor %}
<div class="row">
<div class="form-group col-md-12 text-left px-0">
<label for="email">Email</label>
<input class="border rounded-2 p-3 bg-input " type="email" name="email" id="email" placeholder="Email ">
</div>
<div class="form-group col-md-12 text-left px-0">
<label for="password">Password </label>
<input class="border rounded-2 p-3 bg-input " type="password" class="form-control" id="password" name="password">
</div>
<button class="btn btn-sm btn-dark col-12 rounded-2 my-4 p-3" type="submit">Login </button>
</div>
</form>
my view:
from django.contrib.auth import authenticate,login
from django.shortcuts import render,redirect
from django.contrib.auth.models import auth,Group
from django.contrib import messages
from django.conf import settings
from django.contrib.auth.decorators import login_required
from .decorators import uthenticated_user
from app.models import *
# Create your views here.
#uthenticated_user
def login(request):
if request.method=='POST':
email=request.POST['email']
password=request.POST['password']
user=authenticate(request,email=email,password=password)
if user is not None:
login(request,user)
return redirect('user_home')
else:
messages.error(request,'There was a problem logging in. Check your email and password or create an account')
return redirect('login')
else:
return render(request,'registration/sign-in.html')
As i know, authenticate is only taking username and password. You can try to find username by email firstly and then authenticate him:
#uthenticated_user
def login(request):
if request.method=='POST':
email=request.POST['email']
password=request.POST['password']
# New code
try:
username = User.objects.get(email=email).username
except User.DoesNotExist:
username = None
user=authenticate(request,username=username,password=password)
if user is not None:
login(request,user)
return redirect('user_home')
else:
messages.error(request,'There was a problem logging in. Check your email and password or create an account')
return redirect('login')
else:
return render(request,'registration/sign-in.html')
I was trying to customized django login form. but it throws error like this TypeError at /login/ __init__() takes 1 positional argument but 2 were given. I have created my own form and not using django built in forms. My Project structure looks like this
project_name
apps
app1
app2
static
templates
app1
login.html
app2
app1 contains the basic home, login, signup template file
url.py file inside app1 looks like this
from django.urls import path
from .views import home
from django.contrib.auth import views as auth_views
app_name = "basics"
urlpatterns = [
path('home/', home, name="home_page"),
path('login/', auth_views.LoginView,{'template_name': 'basics/login.html'}, name="login")
]
login.html file resides under templates/app1/login.html and its template looks like this.
{% extends 'basics/home.html' %}
{% block body %}
{% load static %}
<script src="{% static 'js/login.js' %}"></script>
<div class="container">
<div class="row">
<div class="col-sm-9 col-md-7 col-lg-5 mx-auto">
<div class="card card-signin my-5">
<div class="card-body" style="background-color: azure">
<h3 class="card-title text-center">Log In</h3>
<br>
<br>
<p class="text-center">How did you signup?</p>
{{ error }}
<div class="main" id="mainForm">
<br>
<form class="form form-group" method="POST" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<input name ="username" class="form-control" placeholder="Enter Username" required="required">
</br>
<input name="password" class="form-control" placeholder="Enter Password" type="password"
required="required">
</br>
<button class="btn btn-block btn-dark btn-sm" type="submit">Submit</button>
<br>
back
</form>
</div>
<div class="dummybutton">
</br>
<button class="btn btn-sm btn-block emailbutton" style="background-color: skyblue">Email</button>
<button class="btn btn-sm btn-block facebookbutton" style="background-color:aqua">Facebook</button>
</br>
</div>
<br>
<br>
<br>
</div>
</div>
<p class="text-center">Dont have a Profile? Sign up now</p>
</div>
</div>
</div>
{% endblock body %}
view.py file looks like this
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth import authenticate, login as login_check
def home(request):
result = {}
return render(request, 'basics/home.html', result)
def login(request):
result = {'error': 'No error'}
if request.method == "POST":
username = request.POST["username"]
password = request.POST["passsword"]
user = authenticate(request, username=username, password=password)
if user is not None:
login_check(request, user)
redirect('home/')
else:
result = {'error':'Invalid User'}
return render(request, 'basics/home.html', result)
return render(request, 'basics/home.html', result)
You use the LoginView the wrong way, you need to add .as_view() to convert the class-based view to a function, like:
app_name = 'basics'
urlpatterns = [
path('home/', home, name="home_page"),
path('login/', auth_views.LoginView.as_view(template_name='basics/login.html'), name="login")
]
I have a problem that is that Django is not rendering one of the fields of my Login form. I'm using the auth_views.LoginView view for user authentication, and even if I put my template, one of the fields does not appear in my html.
Url.py:
from django.urls import path, re_path
from django.contrib.auth import views as auth_views
from Turnos import views
urlpatterns = [
path('', views.home, name='home'),
with views.login view it works perfectly
#path('login/', views.login, name='login'),
with auth_views.LoginView.as_view(template_name='login.html') doesn't render the email field
path('login/', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
]
views.py:
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib.auth import login as auth_login
from Turnos.forms import loginForm
def login(request):
if request.method == 'POST':
form = loginForm(request.POST)
if form.is_valid():
user = form.save()
auth_login(request, user)
return redirect('nuevoTurno.html')
else:
form = loginForm()
return render(request, 'login.html', {'form': form})
forms.py:
from django import forms
from django.contrib.auth.models import User
class loginForm(forms.ModelForm):
email = forms.EmailField(required=True, widget=forms.EmailInput())
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ['email', 'password']
Html:
<form action="/login/" method="post" novalidate>
{% csrf_token %}
<div class="form-group">
<label for="{{ form.email.label }}" class="">Email</label>
{% render_field form.email class+="form_control form-control-lg" placeholder="Email" %}
</div>
<div class="form-group">
<label for="{{ form.password.label }}" class="">Password</label>
{% render_field form.password placeholder="Password" class+="form_control form-control-lg" %}
</div>
<div class="form-group">
<button type="submit" class="btn btn-outline-light btn-block">
Enviar
</button>
</div>
<div class="form-group">
Lost password?
</div>
</form>
the email field is not displayed with auth_views.loginview
sorry for my English.
It looks like you're using a third part plugin to render individual form fields (I assume you have used {% load widget_tweaks %} in your base.html template.
Perhaps try:
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
...or...
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
Or even...
{{ form.non_field_errors }}
<div class="form-group">
{{ form.email.errors }}
<label for="{{ form.email.id_for_label }}">Email</label>
{{ form.email }}
</div>
If the above doesn't work, then it is time to debug why email isn't pulling through. Not sure if it's an ordering thing (unlikely):
email = forms.EmailField(widget=forms.EmailInput(), attrs={'class': "form_control form-control-lg", 'placeholder': "Email"}, required=True, )
^ I've also added the Django way of passing in attributes to your form fields.
I implemented Login and it works good except error message.
If I used {{ form.as_p }}, it shows error message.
<form id="loginform" class="form-horizontal" role="form" method="post" action="{% url 'users:login' %}">
{% csrf_token %}
<!-- id / pw -->
{{ form.as_p }}
<div class="form-group">
<!-- Button -->
<div class="btn-controls">
<div class="row">
<input id="btn-login" class="btn btn-success" type="submit" name="login_submit" value="로 그 인" />
<input type="hidden" name="next" value={{ request.GET.next}} />
<a id="btn-fblogin" href="{% url 'social:begin' backend='facebook' %}" class="btn btn-primary col-xs-12"><i class="icon-facebook"></i> 1초만에 페이스북으로 로그인 </a>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-12 control">
<div class="signup">
아직 차차다방 회원이 아니세요?  
가입하기
</div>
<div class="forget">
비밀번호를 잊어버리셨나요?
</div>
</div>
</div>
</form>
But when I change template like this, it doesn't show any error when I type wrong id or pw...
<form id="loginform" class="form-horizontal" role="form" method="post" action="{% url 'users:login' %}">
{% csrf_token %}
<div class="input-group">
<span class="input-group-addon"><i class="icon-user"></i></span>
<input id="id_username" type="text" class="form-control" name="username" value="" placeholder="username">
</div>
<div class="input-group">
<span class="input-group-addon"><i class="icon-lock"></i></span>
<input id="id_password" type="password" class="form-control" name="password" placeholder="password">
</div>
<div class="form-group">
<!-- Button -->
<div class="btn-controls">
<div class="row">
<input id="btn-login" class="btn btn-success" type="submit" name="login_submit" value="로 그 인" />
<input type="hidden" name="next" value={{ request.GET.next}} />
<a id="btn-fblogin" href="{% url 'social:begin' backend='facebook' %}" class="btn btn-primary col-xs-12"><i class="icon-facebook"></i> 1초만에 페이스북으로 로그인 </a>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-12 control">
<div class="signup">
아직 차차다방 회원이 아니세요?  
가입하기
</div>
<div class="forget">
비밀번호를 잊어버리셨나요?
</div>
</div>
</div>
</form>
How can I make it show error message even if I don't user {{ form.xx }} ?
Here is my LoginView.
from django.utils.http import is_safe_url
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login
from django.utils.decorators import method_decorator
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.debug import sensitive_post_parameters
from django.views.generic import FormView
from users.forms import MyUserCreationForm
class LoginView(FormView):
form_class = AuthenticationForm
redirect_field_name = REDIRECT_FIELD_NAME
# template_name is fake one.
# This view only process POST request from users/login_signup.html
template_name = "users/login_signup.html"
#method_decorator(sensitive_post_parameters('password'))
#method_decorator(csrf_protect)
#method_decorator(never_cache)
def dispatch(self, request, *args, **kwargs):
# Sets a test cookie to make sure the user has cookies enabled
request.session.set_test_cookie()
return super(LoginView, self).dispatch(request, *args, **kwargs)
def form_valid(self, form):
auth_login(self.request, form.get_user())
# If the test cookie worked, go ahead and
# delete it since its no longer needed
if self.request.session.test_cookie_worked():
self.request.session.delete_test_cookie()
return super(LoginView, self).form_valid(form)
def get_context_data(self, *args, **kwargs):
context = super(LoginView, self).get_context_data(*args, **kwargs)
return context
def get_success_url(self):
return self.request.POST.get("next")
I didn't get what exactly your question is, and also don't know if it is your answer or not, but i just say it!
You should use your django form that you passed from view in your template to be able to validate the form after the submission of form.
and if your concern is how to show the form properly in they way you want, it has another solution. you can represent the form in the way you want like something below:
{% for field in form %}
<div class="input-group">
{% if field.name=="username" %}
<span class="input-group-addon"><i class="icon-user"></i></span>
<input id="id_username" type="text" class="form-control" name="username" value="" placeholder="username">
{% endif %}
{% if field.name=="password" %}
<span class="input-group-addon"><i class="icon-lock"></i></span>
<input id="id_password" type="password" class="form-control" name="password" placeholder="password">
{% endif %}
{% for error in field.errors %}
{{ error }}
{% endfor %}
</div>
{% endfor %}
As you can see, you can access the error of fields via field.errors and check the name of field with field.name!