I'm trying to create custom authentication in Django where the identifier is an email, there is a required field called name and a password field. The login view works fine, but I get an error username from the forms.
Here is my views.py
def auth_login(request):
if request.method == 'POST':
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect("/tasks/")
else:
return HttpResponse('Invalid login.')
else:
form = UserCreationForm()
return render(request, "registration/login.html", {
'form': form,
})
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
new_user = authenticate(email=request.POST['email'], password=request.POST['password1'])
login(request, new_user)
return HttpResponseRedirect("/tasks/")
else:
form = UserCreationForm()
return render(request, "registration/register.html", {
'form': form,
})
Here is my register.html
<form class="form-signin" role="form" method="post" action="">
{% csrf_token %}
<h2 class="form-signin-heading">Create an account</h2>
<input type="text" name="name" maxlength="30" class="form-control" placeholder="Username" required autofocus>
<br>
<input type="email" name="email" class="form-control" placeholder="Email" required>
<br>
<input type="password" name="password1" maxlength="4096" class="form-control" placeholder="Password" required>
<br>
<input type="password" name="password2" maxlength="4096" class="form-control" placeholder="Password confirmation" required>
<input type="hidden" name="next" value="/tasks/" />
<br>
<button class="btn btn-lg btn-primary btn-block" type="submit">Create the account</button>
</form>
{% if form.errors %}
{% for error in form.errors %}
{{ error }}
{% endfor %}
{% endif %}
This prints the error username. What's wrong here?
You'll need to create your own form instead of using django's own UserCreationForm. Django's form requires you to have a username.
You don't have a username, so Django's form will not work for you. So... create your own. See also Django 1.5: UserCreationForm & Custom Auth Model, and especially the answer https://stackoverflow.com/a/16570743/27401 .
Related
raise ValueError('The given username must be set') using django python
...
I have been trying to register a user using from django.contrib.auth.models import user
Views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth.models import User
# Create your views here.
def register(request):
if request.method == 'POST':
username = request.POST.get('username')
email = request.POST.get('email')
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
if password1 == password2:
if User.objects.filter(username = username).exists():
return redirect('register')
elif User.objects.filter(email = email).exists():
return redirect('register')
else:
user=User.objects.create_user(username = username,password =password1, email = email)
user.save()
return redirect('login')
else:
return redirect('/')
else:
return render(request, 'register.html')
def login(request):
return render(request, 'login.html')
register.html
<form method="POST" action="{% url 'register' %}">
{% csrf_token %}
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" id="username">
</div>
<div class="form-group">
<label for="password1">Password</label>
<input type="password" class="form-control" id="password1">
</div>
<div class="form-group">
<label for="password2">AGAIN Password</label>
<input type="password" class="form-control" id="password2">
</div>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" id="email" placeholder="name#example.com">
</div>
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="check">
<label class="form-check-label" for="check">Check me out</label>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
user=User.objects.create_superuser(username = username,password =password1, email = email)
I want to know that why it is just sending that The given username is must be set but instead I have set super_user already. How to resolve this? It is not getting the username by POST method or is there any other mistake which I am ignoring?
add name attribute in your input tags, something like this:
...
<input type="text" class="form-control" id="username" name="username">
...
<input type="password" class="form-control" id="password1" name="password1">
...
<input type="password" class="form-control" id="password2" name="password2">
...
<input type="email" class="form-control" id="email" name="email" placeholder="name#example.com">
...
I think your problem here is the use of request.POST. If this is a form, you probably want to change this to be request.form wherever you're using request.POST. At the moment, your line request.POST.get("username") is returning None, so when you try to save the user it complains.
The Authentication system might be a little bit tricky if this is your first time doing it. I am going to link you with this project that i did a while ago; it has an authentication system with Django; it can help you out :
https://github.com/Nouamanezh909/BLog_repo.
--Go to Accounts, there you will find (
forms , view , everything you need.
)
When a new user signs up for an account, the admin panel shows that a password has not been set for the user (despite saving it via views.py). Another strange thing I noticed is that the password is being saved to the email field in the database. The code appears fine. Not sure where I went wrong. Any help would be greatly appreciated.
sign up html template
{% if user.is_authenticated %}
<h2>currently logged in as {{ user.username }} </h2>
{% else %}
<h1 class="h5 text-center">Create Account</h1>
<h4>{{ error }}</h4>
<form method="POST">
{% csrf_token %}
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" name="username" autocomplete="username" placeholder="Username" id="id_username" required>
</div>
<div class="form-group">
<label for="password1">Password</label>
<input type="password" class="form-control" name="password1" placeholder="Password" autocomplete="new-password" required id="id_password1">
<small>Password must be at least 8 characters</small>
</div>
<div class="form-group">
<label for="password2">Confirm Password</label>
<input type="password" class="form-control" name="password2" placeholder="Confirm Password" autocomplete="new-password" required id="id_password2">
</div>
<ul>
<li>Your password can’t be too similar to your other personal information.</li>
<li>Your password must contain at least 8 characters.</li>
<li>Your password can’t be a commonly used password.</li>
<li>Your password can’t be entirely numeric.</li>
</ul>
<!-- <div class="form-group">
<div class="custom-control custom-checkbox text-small">
<input type="checkbox" class="custom-control-input" id="sign-up-agree">
<label class="custom-control-label" for="sign-up-agree">I agree to the <a target="_blank" href="utility-legal-terms.html">Terms & Conditions</a>
</label>
</div>
</div> -->
<button class="btn btn-primary btn-block" type="submit">Create Account</button>
</form>
views.py
def signup(request):
if request.method == 'GET':
return render(request, 'events/signup.html', {'form': UserCreationForm()})
else:
# Create new user and profile
if request.POST['password1'] == request.POST['password2']:
try:
print(request.POST['password1'])
print(request.POST['password2'])
user = User.objects.create_user(request.POST['username'], request.POST['password1'])
user.save()
login(request, user)
return redirect('home')
except IntegrityError:
return render(request, 'events/signup.html', {'form': UserCreationForm(), 'error':'Username has already been taken. Please use a different name.'})
else:
# Tell the user the passwords don't match
return render(request, 'events/signup.html', {'form': UserCreationForm(), 'error':'Passwords did not match'})
There's no mention of "email" anywhere in the code but for some reason the password gets saved as email and the actual password isn't getting set.
You need to set password explicitly, or send it in the third param, second param of create_user method is email, thats why password is being set as email.
reference to set_password method
reference to create_user method
You need something like this.
user = User.objects.create_user(username=request.POST['username'])
user.set_password('new password')
user.save()
Your code:
user = User.objects.create_user(request.POST['username'], request.POST['password1'])
user.save()
See the the docs:
create_user(username, email=None, password=None, **extra_fields)
So, oops, you send the password as second argument and it is interpreted as being the email address.
create_user(username=request.POST['username'], password=request.POST['password1'])
Should work.
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'm trying to write a simple app that let users to login, in Django. I've downloaded a pretty bootstrap login template, but I can't hook it up to my Django project. When I click submit, nothing happens, Here's the view:
def login_view2(request):
if request.method == 'POST':
print("POST METHOD")
form = LoginForm(request.POST)
if form.is_valid():
print("FORM VALID")
uname = form.cleaned_data['username']
pword = form.cleaned_data['password']
user = authenticate(username=uname, password=pword)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect('/')
else:
print("The account has been disabled!")
else:
print("The username and password were incorrect!")
else:
print("LOGIN FORM SHOWN")
form = LoginForm()
return render(request, 'login2.html', {'form': form})
and here's the form
<form id="login-form" action="login2/" method="post">
{% csrf_token %}
<div class="modal-body">
<div id="div-login-msg">
<div id="icon-login-msg" class="glyphicon glyphicon-chevron-right"></div>
<span id="text-login-msg">Type your username and password.</span>
</div>
<input id="login_username" class="form-control" type="text" placeholder="Username" required>
<input id="login_password" class="form-control" type="password" placeholder="Password" required>
</div>
<div class="modal-footer">
<div>
<input type="submit">Login</input>
</div>
</div>
</form>
Thank you very much in advance!
You haven't given your HTML fields a name attribute, so the browser can't send any data to the server.
Also you need to display errors for when the form is not valid, using {{ form.errors }}.
I know it is basic to create login User Authentication. And I am a newbie here in using Django.
I have a problem in creating User Authentication:
Views.py
def Logins(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None and user.is_active:
login(request, user)
return HttpResponseRedirect('music/login')
return HttpResponseRedirect('music/login')
form = Userlogin
return render(request, 'music/login.html', {'Login_form': Userlogin})
urls.py
url(r'^login/$', views.Logins, name='login'),
It shows
It shows MultiValueDictKeyError at /music/login/.
"'username'"
Request Method: POST
Request URL: http://127.0.0.1:8000/music/login/
Django Version: 1.10.4
Exception Type: MultiValueDictKeyError
Exception Value:
"'username'"
login.html
{% block body %}
{% if form.errors %}
<p>Something is wrong</p>
{% endif %}
<form action="" method="post">
{% csrf_token %}
<label for="email">Login:</label>
<label for="password">Password:</label>
<input type="password" name="password" value="" id="username">
<input type="submit" value="login" />
</form>
{% endblock %}
Thanks in advance.
The MultiValueDictKeyError seems to be because request.POST['username'] does not exist.
Add a username field in your login form.
<form action="" method="post">
{% csrf_token %}
<label for="username">Username:</label>
<input type="text" name="username">
<label for="email">Login:</label>
<label for="password">Password:</label>
<input type="password" name="password" value="" id="username">
<input type="submit" value="login" />
</form>
request.POST is a dictionary. You should be doing it this way:
username = request.POST.get('username', None)
password = request.POST.get('password', None)