Am able to register users successfully in my register view,however when i try to login using those credentials in the user_login view,am redirected to a page that says my credentials are wrong.whats the problem ? Here is the code.
user_login view
def user_login(request):
if request.method == '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('/rango/')
else:
return HttpResponse("your acc was disabled")
else:
print "Invalid login details: {0}, {1}".format(username, password)
return HttpResponse('Invalid login details')
else:
return render(request,'login.html', {})
login template
Rango
<body>
<h1>Login to Rango</h1>
<form id = "login_form" method = "post" action = "/rango/login/">
{% csrf_token %}
Username: <input type = "text" name = "username" value="" size="50"/>
<br/>
Password: <input type = "password" name = "username" value="" size="50"/>
<br/>
<input type = "submit" value = "submit"/>
</form>
</body>
You have the wrong name for your password input. It should be:
Password: <input type = "password" name = "password" value="" size="50"/>
Related
I have 2 login page - login_admin and login_user for admin and normal user respectively.
When user enter username and password in login_admin and login_user page, it will check whether user is_staff is True or False.
If user is_staff = True, then allow the user login admin page.
My problem is: The user can't login to admin page although is_staff = True. The user is able to login to normal user page although is_staff = True. I don't know where is the problem.
Here is my code in views.py:
def login_admin(request):
context = {}
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
if username and password:
user = authenticate(username=username, password=password)
if user:
if request.user.is_staff:
login(request, user)
return redirect('/home/')
else:
context['error'] = "You are authenticated but are not authorized to access this page. Would you like to login to a different account?"
return render(request, 'registration/login.html',context)
else:
context['error'] = "Invalid username or password!"
return render(request, 'registration/login.html',context)
return render(request, 'registration/login.html')
def login_user(request):
context = {}
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
if username and password:
user = authenticate(username=username, password=password)
if user:
if not request.user.is_staff:
login(request, user)
return redirect('/cust/home/')
else:
context['error'] = "Invalid username or password!"
return render(request, 'registration/custlogin.html',context)
else:
context['error'] = "Invalid username or password!"
return render(request, 'registration/custlogin.html',context)
return render(request, 'registration/custlogin.html')
login.html
{% extends 'base.html' %}
{% block title %}Login{% endblock %}
{% block content %}
<h2>Admin Login Screen</h2>
Customer Login Page
<form method="post">
{% csrf_token %}
<table cellpadding="10">
<tr>
<td><label for="usename">Username: </label></td>
<td><input type="text" name="username" id="username" required></td>
</tr>
<tr>
<td><label for="password">Password: </label></td>
<td><input type="password" name="password" id="password" required></td>
</tr>
<p style="color:red; font-weight: bold">{{ error }}</p>
</table>
<button type="submit" class="btn btn-primary">Login</button>
</form>
{% endblock %}
url.py
url(r'accounts/login/', customers.views.login_admin,name='login_admin'),
url(r'accounts/custlogin/', customers.views.login_user,name='login_user'),
url(r'accounts/logout/', customers.views.logout_user,name='logout_user'),
UPDATED:
I'm not able to sign in to admin page when is_staff = True / False which will return error You are authenticated but are not authorized to access this page. Would you like to login to a different account? which is written in my code, but able to sign in to user page when is_staff=True / False.
If i remove if user.is_staff, it works for admin and normal user.
urls.py
url(r'^accounts/login/$', customers.views.login_admin,name='login_admin'),
url(r'^accounts/custlogin/$', customers.views.login_user,name='login_user'),
url(r'^accounts/logout/$', customers.views.logout_user,name='logout_user'),
UPDATED V2:
I've tried the code that written by #Rarblack but still get error : 'QuerySet' object has no attribute 'is_staff'.
So I've modified the code and it works.
from django.contrib.auth.models import User
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
if username and password:
user = authenticate(username=username, password=password)
if user:
user_instance = User.objects.filter(Q(username_exact=username) & Q(is_staff=True))
if user_instance:
login(request, user)
return redirect('/home/')
else:
....
As seen from your code you are getting password and username from the login form and your implementation of it is not correct. You should have used django form or ModelForm and get the input from cleaned_data dict. It should have been something like this:
if request.method == 'POST':
form = ExampleForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data'password']
if username and password:
user = authenticate(username=username, password=password)
......
When we come to your issue, the problem is in this part:
if not request.user.is_staff:
login(request, user)
return redirect('/cust/home/')
what you are basically is doing letting non-staff users in. Change it to:
if request.user.is_staff:
login(request, user)
return redirect('/cust/home/')
EIDT: You are missing request part in the authenticate() method also try this:
user = authenticate(request, username=username, password=password)
if user:
if not user.is_staff:
The problem is that you cannot check any user's staff status because at that time there is no any user logged in to check. So request.user will not return a user. But you can try this:
from django.contrib.models import User
from django.shortcuts import get_object_or_404
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
if username and password:
user = authenticate(username=username, password=password)
if user:
user_instance = User.objects.filter(username_exact=username)
if user_instance.is_staff:
login(request, user)
return redirect('/home/')
else:
....
You use if not request.user.is_staff: in both views. For login_admin, if you only want staff to be able to log in, you should change it to:
if request.user.is_staff:
Here is my views.py
views.py
def user_login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username = username , password = password)
if user:
if user.is_active:
login(request , user)
return HttpResponseRedirect('/zdorovo/')
else:
return HttpResponse('You dont have an account with us')
else:
print "Invalid Login Details: {0} , {1}".format(username , password)
return HttpResponse('Invalid Login Details ')
else:
render(request , 'zdorovo/login.html' , {})
authenticate , login , HttpResponse , HttpResponseRedirect have been imported correctly. I also took care of Indentation , so the error is not raising from that end.
Please help me understand the error.
Here is my login.html
<body>
<h1>Login</h1>
<form id="login_id" method="post" action="/zdorovo/login/">
{% csrf_token %}
Username: <input type="text" name="username" value=""/>
<br/>
Password: <input type="password" name="password" value=""/>
<br/>
<input type="submit" value="Login" />
</form>
</body>
P.S.:- Update me if you need other scripts from my end.
Your function doesn't return anything when it executes the last else condition you should add a return statements.
return render(request , 'zdorovo/login.html' , {})
problem with my assignment....
I also need to make users login based on whether their role (usertype) is 'reader' or 'client' to be redirected to the proper welcome page. Plus i want to use my custom model (User's username & password) for login credentials. I have read the django docs custom auth but i still don't know i will implement it into my project.
models.py
class User(models.Model):
id = models.AutoField(primary_key=True, unique=True)
title = models.CharField(max_length='10')
surname = models.CharField(max_length='50')
firstname = models.CharField(max_length='50')
username = models.CharField(max_length='50', unique=True)
password = models.CharField(max_length='50')
email = models.EmailField(max_length='50')
phone = models.BigIntegerField(max_length='12')
city = models.CharField(max_length='50')
country = models.CharField(max_length='50')
usertype = models.CharField(max_length=13)
views.py
def login(request):
c = {}
c.update(csrf(request))
return render_to_response('login.html', c)
def auth_view(request):
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return HttpResponseRedirect('adminwelcome')
else:
return HttpResponseRedirect('invalid')
template
{% extends "main.html" %}
{% block title %}Log In - {{ block.super }}{% endblock %}
{% block content %}
{% if form.errors %}
<p>Sorry, that is not a valid username or password</p>
{% endif %}
<form action = "auth_view" method="post"> {% csrf_token %}
<label for="username">Username:</label>
<input type="text" name="username" value="" id="username" />
<br />
<label for="password">Password:</label>
<input type="password" name="password" value="" id="password" />
<br />
<input type="submit" value="Login" />
</form>
<p>Not Registered? Create Account </p>
{% endblock %}
What i did was that when my User model form is being saved, it should get the username, password and email and create a user in the Django auth User table using this line of code
User.objects._create_user(request.POST['username'], request.POST['email'], request.POST['password'],False,False)
This is the full code in the views.py
def register(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
User.objects._create_user(request.POST['username'], request.POST['email'], request.POST['password'],False,False)
# Redirect to the document list after POST
return HttpResponseRedirect('register_success')
else:
form = RegisterForm()
args = {}
args.update(csrf(request))
args['forms'] = RegisterForm()
return render_to_response('register.html', args)
Then for the login based on roles, I had to make the user a staff from the admin end by setting the 'is_staff' = true. After that, all i had to do was pass the 'is_staff==True' in the auth_view request during login authentication. A bit dirty but it does the trick. Any further optimization is appreciated. Cheers.
Views.py
def auth_view(request):
username1 = request.POST.get('username', '')
password1 = request.POST.get('password', '')
user = auth.authenticate(username=username1, password=password1)
#check if user has been set to staff (reader), redirect to reader welcome
if user is not None and user.is_staff==True:
auth.login(request, user)
return HttpResponseRedirect('readerwelcome')
#check if user is not staff(client), redirect to client welcome
elif user is not None:
auth.login(request, user)
return HttpResponseRedirect('clientwelcome')
#if login details not found, return error page
else:
return HttpResponseRedirect('invalid')
I am trying to write my method to add a User type object on registration. Here is the code:
views.py
def registration(request):
c= {}
c.update(csrf(request))
state = "Please Register below..."
username = None
email = None
password = None
user_success = None
user_created = None
if request.POST:
username = request.POST.get('username')
email = request.POST.get('email')
password = request.POST.get('password')
print "username ",username
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
user_created = True
else:
user_created = False
else:
user = User.objects.create_user(username=username,password=password,email=email)
user.save()
user.is_active = True
user_success = True
return render_to_response('register.html',{'success':user_success,'created':user_created,'username': username},context_instance = RequestContext(request))
forms.py
class RegistrationForm(forms.Form):
username = forms.CharField()
email = forms.EmailField()
password = forms.CharField()
templates/register.html is:
{% extends "base.html" %}
{% block pageContent %}
<div class="container">
<form action="/register" method="post">
{% csrf_token %}
username:
<input type="text" name="username" value="{{ username}}" /><br />
password:
<input type="password" name="password" value="" /><br />
Email:
<input type="text" name="email" value="{{email}}" /><br />
<input type = 'submit' value='Register' />
</form>
</div>
{% endblock %}
Can anyone please help me spot the error? Also let me know if I am doing the registration right
The value of username at this point must evaluate to True.
user = User.objects.create_user(username=username,password=password,email=email)
# ^^^^^^^^ this can't be a bool() false
Why? That error message is very specific.. it's called from this specific place in django auth:
def create_user(self, username, email=None, password=None, **extra_fields):
"""
Creates and saves a User with the given username, email and password.
"""
now = timezone.now()
if not username:
raise ValueError('The given username must be set')
Can you be 100% positive username is the right value? It sounds like it's an empty string.
I found the error. The error was in indentation of the view.py.
if user is not None:
part of the code should be only if the request type is POST. So that needed indentation.
I have a simple signup form (in signup.html)
<form action="adduser" method="post">
{% csrf_token %}
Email Address: <input type="email" name="email" required autocomplete="on" placeholder="fr#star.com"/><br/>
Username: <input type="text" name="username" maxlength=25 required placeholder="JoyfulSophia"/><br/>
Password: <input type="password" name="password" maxlength=30 required placeholder="**********" /><br/>
<br/>
<input type="submit" value="Send" /> <input type="reset">
</form>
This redirects to the addUser view:
def adduser(request):
u = User.objects.create_user(request.POST['username'], request.POST['email'], password=request.POST['password'])
u.save()
a = Accounts(user=u)
p = Passwords(user=u)
a.save()
p.save()
return HttpResponseRedirect(reverse('OmniCloud_App.views.profile', args=(u.id,)))
Here is the profile:
#login_required
def profile(request, User_id):
u = get_object_or_404(User, pk=User_id)
a = get_object_or_404(Accounts, pk=User_id)
return render_to_response('profile.html', context_instance=RequestContext(request))
So they wouldn't be signed in, but that's okay because we can send you over to /accounts/login?next=/7/ since they are user 7 (Problems Ahead!)
def login(request):
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None and user.is_active:
auth.login(request, user)
return HttpResponseRedirect("/account/profile/")
else:
return HttpResponseRedirect("/account/invalid/")
The request doesn't contain anything called username, but the one which was submitted to the addUser form does, so how can I shoot that bro over to login? I could have it parse the url (which contains the next=USER_ID) but that wouldn't work for someone that just types in base_url/login, and the user_id won't be part of the url forever. So what's a brother to do?
Post data exists only for one request. If you want to use it later you should save it somewhere else.
You could login the user right after registration, in adduser view, he just entered his username and password, he doesn't have to do it again.
And login view is a little off. This is just a "POST" part of the view. You need to check and see if it's GET request and if it is return template with form containing username and password fields and with target url that points to the same view. Something like this:
def login(request):
if request.method == 'GET':
return render_to_response('login.html',
{ 'form': LoginForm() },
context_instance=RequestContext(request))
elif request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = auth.authenticate(username=username, password=password)
if user is not None and user.is_active:
auth.login(request, user)
return HttpResponseRedirect("/account/profile")
else:
return HttpResponseRedirect("/account/invalid/")
Where login.html is something like this:
{% extends "base_site.html" %}
{% block content %}
<form method="post" target="{% url login_view %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Login" />
</form>
{% endblock content %}
Also, you could return user to the same login form if username and password didn't match and add some message!
This is just from the top of my head, didn't try it, but it should work!
There is an extensible user-registration application for Django called django-registration that offers you a lot of functionality for creating and registering users. Setting it up is very simple, you can find a very good doc here