I am not using django default admin dashboard and i am using my own custom template for the admin.but here i got some problem while editing and updating the user.I want to make email of every user unique in the database this code in my forms.py does pretty well while adding the user but while updating it i got some problem regarding the email.Since I have done the email unique in forms.py it is giving me error while updating also.How can i update users so that the edited user can have the same email but not same as the other user's email address.
forms.py
class RegisterForm(UserCreationForm):
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise ValidationError('Email Already Exists')
return email
class Meta:
model = User
fields = ['username', "email", "password1", "password2",'is_superuser','is_staff','is_active']
views.py
def register(request):
if not request.user.is_superuser:
messages.warning(request, 'Permission Denied.You have no permission to register users.')
return redirect('students:home')
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.save()
messages.success(request,'user created with username {}'.format(user.username))
return redirect('students:our_users')
else:
form =RegisterForm()
return render(request,'students/register.html',{'form':form})
def editusers(request,id):
if not request.user.is_superuser:
messages.warning(request, 'Permission Denied.You have no permission to perform this action.')
return redirect('students:our_users')
user = User.objects.get(id=id)
return render(request,'students/edit_users.html',{'user':user})
def updateusers(request,id):
if not request.user.is_superuser:
messages.warning(request, 'Permission Denied.You have no permission to perform this action.')
return redirect('students:our_users')
user = User.objects.get(id=id)
form = RegisterForm(request.POST,instance=user)
if form.is_valid():
user = form.save(commit=True)
user.save()
messages.success(request,'{} updated'.format(user.username))
return redirect('students:our_users')
else:
messages.error(request,'Error in Form')
return redirect('students:edit_user',user.id)
register template
<form action="" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<div class="text-xs-right">
<button type="submit" class="btn btn-info">Add</button>
</div>
</form>
edituser template
<form action="{% url 'students:update_user' user.id %}" method="post">
{% csrf_token %}
<div class="form-group"><label for="id_username">Username</label><input type="text" name="username" maxlength="150" autofocus class="form-control" value="{{user.username}}" placeholder="Username" title="Required. 150 characters or fewer. Letters, digits and #/./+/-/_ only." required id="id_username">
<small class="form-text text-muted">Required. 150 characters or fewer. Letters, digits and #/./+/-/_ only.</small>
</div>
<div class="form-group"><label for="id_email">Email</label><input type="email" name="email" value="{{user.email}}" class="form-control" placeholder="Email" title="" required id="id_email"></div>
<div class="form-group"><label for="id_password1">Password</label><input type="password" name="password1" value="{{user.password}}" class="form-control" placeholder="Password" title="Your password must contain at least 8 characters.Your password can't be entirely numeric." required id="id_password1">
<small class="form-text text-muted"><ul><li>Your password must contain at least 8 characters.</li><li>Your password can't be entirely numeric.</li></ul></small>
</div>
<div class="form-group"><label for="id_password2">Password confirmation</label><input type="password" name="password2" value="{{user.password}}" class="form-control" placeholder="Password confirmation" title="Enter the same password as before, for verification." required id="id_password2">
<small class="form-text text-muted">Enter the same password as before, for verification.</small>
</div>
<div class="form-group"><div class="form-check"><input type="checkbox" name="is_superuser" {% if user.is_superuser %}checked="checked" {% endif %}
class="form-check-input" id="id_is_superuser"><label class="form-check-label" for="id_is_superuser" title="Designates that this user has all permissions without explicitly assigning them.">Admin status</label>
<small class="form-text text-muted">Designates that this user has all permissions without explicitly assigning them.</small>
</div></div>
<div class="form-group"><div class="form-check"><input type="checkbox" name="is_staff" {% if user.is_staff %}checked="checked" {% endif %} class="form-check-input" id="id_is_staff"><label class="form-check-label" for="id_is_staff" title="Designates whether the user can log into this admin site.">Staff status</label>
<small class="form-text text-muted">Designates whether the user can log into this admin site.</small>
</div></div>
<div class="form-group"><div class="form-check"><input type="checkbox" {% if user.is_active %}checked="checked" {% endif %} name="is_active" class="form-check-input" id="id_is_active"><label class="form-check-label" for="id_is_active" title="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.">Active</label>
<small class="form-text text-muted">Designates whether this user should be treated as active. Unselect this instead of deleting accounts.</small>
</div></div>
<div class="text-xs-right">
<button type="submit" class="btn btn-info">Update</button>
</div>
</form>
You can do it like this:
def clean_email(self):
email = self.cleaned_data['email']
if self.instance and self.instance.pk:
return email
else User.objects.filter(email=email).exists():
raise ValidationError('Email Already Exists')
return email
Here I am checking if form has any instance and if that instance has any primary key. This instance attribute is set in form when you pass it from view, for example in your code: form = RegisterForm(request.POST,instance=user).
Related
I'm making an lms website. It has classes. Teachers can create new classes and students can add those classes with entering their id and password (if the class has any password). Classes have custom ids and password made by their teachers. The teacher side of the code works fine so I omitted it. But there's a problem in the student part. I have already made a class which requires a password. I enter its id and password in the form and when I submit, it renders the form with the 'message' which has the value: "Invalid id and/or password.". while the password and id match. What is the problem here?
<p style="color: red;">{{message}}</p>
{% if user.is_teacher %}
<form action="{% url 'new_class' %}" method="post">
{% csrf_token %}
<div class="form-group">
<input class="form-control" type="text" name="class-name" placeholder="Class Name" maxlength="64" required>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="class-type" id="class-type">
<label class="form-check-label" for="class-type">
Private
</label>
</div>
<div class="form-group">
<input class="form-control" type="password" name="class-password" id="class-password" placeholder="Password" style="display: none;" maxlength="16">
</div>
<input class="btn btn-primary" type="submit" value="Create">
</form>
{% else %}
<form action="{% url 'new_class' %}" method="post">
{% csrf_token %}
<div class="form-group">
<input class="form-control" type="text" name="class-id" placeholder="Class ID" maxlength="4" required>
</div>
<div class="form-group">
<p><sub>Leave the password field empty if the class doesn't have a password.</sub></p>
<input class="form-control" type="password" name="class-password" id="class-password" placeholder="Password" maxlength="16">
</div>
<input class="btn btn-primary" type="submit" value="Add">
</form>
{% endif %}
The view:
def new_class(request):
if request.method == 'POST':
# teacher user
if request.user.is_teacher:
# some code...
# student user
else:
class_id = request.POST['class-id']
# if user entered a password:
try:
class_password = request.POST['class-password']
# if a class with the entered id existed
try:
newclass = Class.objects.get(class_id=class_id)
# check if the class requires a password
if newclass.class_password is not None:
# if it did, compare the passwords
if newclass.class_password == class_password:
request.user.student_classes.add(newclass)
return HttpResponseRedirect(reverse('index'))
else:
return render(request, 'lms/new-class.html', {
'message': 'Invalid id and/or password.'
})
# if the class didn't have a password, let the user in
else:
request.user.student_classes.add(newclass)
return HttpResponseRedirect(reverse('index'))
except:
return render(request, 'lms/new-class.html', {
'message': 'Invalid id and/or password.'
})
# if user didn't enter any password
except:
try:
# try finding a class with the entered id
newclass = Class.objects.get(class_id=class_id)
# if the class doesn't require a password, let the user in
if newclass.class_password is None:
request.user.student_classes.add(newclass)
return HttpResponseRedirect(reverse('index'))
else:
return render(request, 'lms/new-class.html', {
'message': 'This class requires a password.'
})
except:
return render(request, 'lms/new-class.html', {
'message': 'Invalid id and/or password.'
})
return HttpResponseRedirect(reverse('index'))
else:
return render(request, 'lms/new-class.html')
Also I'm not sure what title to use for this question of mine so I'm open to suggestions.
I have created two different types of users - truck & company. Here is my registration page for a user
After registering, the data about whether the user is a truck or company will go to the database.
In my login page,
only Email and Password are to be entered. In my custom user creation form, I added the field username = email.
When I am trying to login with valid credentials, the page is not redirecting me to a particular page according to the user-type. Instead, an error which I created for invalid credentials in login.html is raising - "Your email and password didn't match. Please try again."
here's my code:
views.py:
def login_view(request):
title = "Login"
if request.method == 'POST':
form = LoginForm(data=request.POST)
email = request.POST.get('email', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=email, password=password)
if form.is_valid():
auth.login(request, user)
user_type = form.cleaned_data['Label']
if user.is_active & user_type == 'Truck':
return HttpResponseRedirect('/post_load/')
elif user_type == 'Company':
return HttpResponseRedirect('/live_deal/')
else:
form = LoginForm()
return render(request, 'registration/login.html', {'form' : form, 'title': title})
urls.py:
# url(r'^login/$', views.login_view),
# url(r'^accounts/login/$', views.login_view),
url(r'^login/$', 'django.contrib.auth.views.login', {'authentication_form': LoginForm}),
url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'authentication_form': LoginForm}),
forms.py:
class LoginForm(auth.forms.AuthenticationForm):
email = forms.EmailField(label=_("Email"),widget=forms.EmailInput)
CHOICES= (('Truck', 'Truck'),('Company', 'Company'),)
Label = forms.ChoiceField(choices=CHOICES, label='Label', widget=forms.RadioSelect())
login.html:
{%extends "registration/header.html"%}
{% block content %}
{% if form.errors %}
<p>Your email and password didn't match. Please try again.</p>
{% endif %}
<form class="form-horizontal" method="post" action = "." >{%csrf_token%}
<div class="panel panel-default login">
<div class="panel-heading">
<span class="glyphicon glyphicon-lock"></span> Login</div>
<div class="panel-body">
<form class="form-horizontal" role="form">
<div class="form-group">
<div class='col-sm-6 col-sm-offset-4'>
<table border="0">
<div class="col-sm-4">
<tr><th><label for="id_user" class="col-sm-4 control-label">Email:</label></th><td>{{ form.email }}</td></tr> </div>
<div class="col-sm-4">
<tr><th><label for="id_password" class="col-sm-4 control-label">Password:</label></th><td>{{ form.password }}</td></tr> </div>
</table> </div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-8">
<div class="checkbox">
<label>
<input type="checkbox"/>
Remember me
</label>
</div>
</div>
</div>
<div class="form-group last">
<div class="col-sm-offset-4 col-sm-8">
<button type="submit" class="btn btn-success btn-sm">
Sign in</button>
<input type="hidden" name="next" value="/" />
<label class="col-sm-offset-3">
Forget Password?
</label>
</div>
</div>
</form>
</div>
<div class="panel-footer">
Not Registered? Register</div>
</div>
</form>
{% endblock %}
{% if form.errors %}
<p>Your email and password didn't match. Please try again.</p>
This error is rather broad. You could loop through it to see the actual errors.
Better yet; don't use your own authentication system just use Django's built-in system which also allows you to add extra fields to the user model.
Example:
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# Redirect to a success page.
else:
# Return a 'disabled account' error message
...
else:
# Return an 'invalid login' error message.
...
Note, you don't need to write your own login view, you can also use Django's login system to handle the form, pass reset/change, urls and templates (which you can override with your own template):
urls:
urlpatterns = [
url('^', include('django.contrib.auth.urls')),
]
Then /login/ will be your login page.
After it works with the Django contrib auth module, extend it with your own custom HTML login form.
django.contrib.auth.views
Below is my code for Form submission .when i submit the form form,is_valid always returning false not sure want went wrong with my code. I am just started learning Django any help is highly appreciated TIA
HTML
{%extends 'base.html'%}
{% block content %}
<div class="container">
<form method="post" class="form-signin" action="/loginvalidation/">{% csrf_token %}
<h2 class="form-signin-heading">Please sign in</h2>
<label for="inputEmail" class="sr-only">Email address</label>
<input type="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required>
<div class="checkbox">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div>
{% endblock %}
Html file
view.py
def loginvalidation(request):
print request
form = LoginssForm(request.POST or None)
print form.is_valid()
if form.is_valid():
save_it=form.save(commit=False)
print save_it.email
save_it.save()
user = authenticate(username='john', password='secret')
if user is not None:
# the password verified for the user
if user.is_active:
print("User is valid, active and authenticated")
else:
print("The password is valid, but the account has been disabled!")
else:
# the authentication system was unable to verify the username and password
print("The username and password were incorrect.")
return render(request,"about-us.html",locals(), context_instance=RequestContext(request))]
View. py for my code
Model.py
class LogIn(models.Model):
email=models.EmailField(null=False,blank=False)
password=models.CharField(max_length=1201,null=True,blank=True)
timestamp=models.DateTimeField(auto_now_add=True,auto_now=False)
updated=models.DateTimeField(auto_now_add=False,auto_now=True)
Model of application
Model of applicationModel of application
form.py
class LogInForm(forms.ModelForm):
class Meta:
model=LogIn
fields = '__all__'
Above is my code for Form submission. When I submit the form, form.is_valid always returns False. I just started learning Django any help is highly appreciated.
It appears you're missing a "name" attribute on your fields in the HTML file, thus the value is never actually getting posted to Django. If just add name="email" and name="password", respectively, to the fields, then the values should get passed through and begin properly validating.
However, that being said, I agree with Alasdair's comment above. It would be far more secure and recommended to use Django's built in authentication system.
I'm trying to build a basic django web application. I am using the authentication and auth model now and my code requires username and password only. How can we make it better by adding password verification step or user id check service?
def authenticate(request):
user = auth.authenticate(username=request.POST['username'], password=request.POST['password'])
if user == None:
return HttpResponse('username or password error')
auth.login(request, user)
#I requested "request"!!!!
return HttpResponseRedirect(request.POST.get('next', '/') or '/')
def signup(request):
return render_to_response('signup_account.html', locals(), RequestContext(request))
def create(request):
#user = User.objects.create_user(username=request.POST['username'], first_name=request.POST['userfirstname'], last_name=request.POST['userlastname'],
# email=request.POST['email'],
# password=request.POST['password'])
user = User.objects.create_user(username=request.POST['username'],
password=request.POST['password'])
print 'create', user
user = auth.authenticate(username=request.POST['username'], password=request.POST['password'])
print 'authenticated', user
auth.login(request, user)
#Here what I want to do is to allow users to screen their wrong id.
#+ Password check.
subject = 'Thank you'
message = 'Welcome home /n I am so happy'
from_email = settings.EMAIL_HOST_USER
to_list = [user.email,settings.EMAIL_HOST_USER ]
send_mail(subject, 'Wow, this email sending altorithm is working.\n What a marvelous function is.', settings.EMAIL_HOST_USER,
to_list, fail_silently=False)
return HttpResponseRedirect(request.POST.get('next', '/') or '/')
The below is the login html code.
<html>
<head>
<link rel="stylesheet" type="text/css" href="/static/css/bootstrap.css">
</head>
<body>
<h1>Sign Up</h1>
<div class="container">
<form class="form" action="/accounts/create" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{csrf_token}}">
<input type="hidden" name="next" value="{{ request.GET.next }}">
<div class="form-group">
<label>User ID</label>
<input class="form-control" type="text" name="username">
</div>
<div class="form-group">
<label>First Name</label>
<input class="form-control" type="text" name="userfirstname">
</div>
<div class="form-group">
<label>Last Name</label>
<input class="form-control" type="text" name="userlastname">
</div>
<div class="form-group">
<label>Email</label>
<input class="form-control" type="email" name="email">
</div>
<div class="form-group">
<label>Password</label>
<input class="form-control" type="password" name="password">
</div>
<input type="submit" class="btn btn-primary" value="Sign Up">
</form>
</div>
</body>
</html>
I'm a really beginner and I am even forced to think that this would be possible by inserting code into html file directly. I'm looking forward to hearing any feedback! Thank you.
You have username and password there ... So pass that into try ...
username = request.POST['username']
password = request.POST['password']
try:
user = User.objects.get(username=username)
if user.check_password(password):
username = user.username
user = authenticate(username=username, password=password)
login(request, user)
messages.success(request, "Welcome")
return HttpResponseRedirect(#your url
else:
messages.error(request, "Password not match")
return HttpResponseRedirect(#your url
except User.DoesNotExist:
pass
views.py to save the password:
elif 'reset_password' in request.POST:
if request.POST['reset_password'].strip():
saveuser = User.objects.get(id=user.id)
saveuser.set_password(request.POST['reset_password']);
saveuser.save()
userform = UserForm(instance=saveuser)
return redirect('incident.views.about_me')
popup box to get the old password and new password
<div id="overlay_form" style="display:none">
<form method="post" action=".">
{% csrf_token %}
<h2>Reset Password</h2><br />
<table>
<tr><td>Enter your old password</td><td>
<input type="text" name="old_password" id="old_password" maxlength="30" /></td></tr>
<tr><td>Enter your new password</td><td><input type="text" name="new_password" id="new_password" maxlength="30" /></td></tr>
<tr><td>Confirm your new password</td><td><input type="text" name="reset_password" id="reset_password" maxlength="30" /></td></tr>
</table>
<div style="width:180px;float:right;margin:20px 5px 0 10px">
{% include "buttons/save.html" %}
<button style="margin-right:10px;" type="button" id="close" name="cancel" class="forward backicon">
<img src="{{ STATIC_URL }}images/button-icon-ir-back.png" width="12" height="17" alt="" />
Cancel</button>
</div>
</form>
</div>
I am able to save the new password,but i want to know the following things
How to check the entered old password is correct with existing password.
How to validate new password field and confirm password field.Which validation is better to perform.
Need some help.
This is how you would check for old password - before the set_password,
user.check_password(request.POST['reset_password'])
Also, check for password confirmation in the following way.
elif 'reset_password' in request.POST:
old_password = request.POST['old_password'].strip()
reset_password = request.POST['reset_password'].strip()
new_password = request.POST['new_password'].strip()
if old_password && reset_password && reset_password == new_password:
saveuser = User.objects.get(id=user.id)
if user.check_password(old_password):
saveuser.set_password(request.POST['reset_password']);
saveuser.save()
userform = UserForm(instance=saveuser)
return redirect('incident.views.about_me')
It is a much better approach to use a form.
Django Code to check if the password entered by user matches the actual old password; if it does not, raise validation error in django form. Also, update the password if both of the passwords match.
Tested on (Django 1.10, Python 3.4)
forms.py
from django import forms
class changePassForm(forms.Form):
old_password_flag = True #Used to raise the validation error when it is set to False
old_password = forms.CharField(label="Old Password", min_length=6, widget=forms.PasswordInput())
new_password = forms.CharField(label="New Password", min_length=6, widget=forms.PasswordInput())
re_new_password = forms.CharField(label="Re-type New Password", min_length=6, widget=forms.PasswordInput())
def set_old_password_flag(self):
#This method is called if the old password entered by user does not match the password in the database, which sets the flag to False
self.old_password_flag = False
return 0
def clean_old_password(self, *args, **kwargs):
old_password = self.cleaned_data.get('old_password')
if not old_password:
raise forms.ValidationError("You must enter your old password.")
if self.old_password_flag == False:
#It raise the validation error that password entered by user does not match the actucal old password.
raise forms.ValidationError("The old password that you have entered is wrong.")
return old_password
views.py
def settings(request):
if request.user.is_authenticated:
form = changePassForm(request.POST or None)
old_password = request.POST.get("old_password")
new_password = request.POST.get("new_password")
re_new_password = request.POST.get("re_new__password")
if request.POST.get("old_password"):
user = User.objects.get(username= request.user.username)
#User entered old password is checked against the password in the database below.
if user.check_password('{}'.format(old_password)) == False:
form.set_old_password_flag()
if form.is_valid():
user.set_password('{}'.format(new_password))
user.save()
update_session_auth_hash(request, user)
return redirect('settings')
else:
return render(request, 'settings.html', {"form": form})
else:
return redirect('login')
settings.html
<h1>Settings Page</h1>
<h2>Change Password</h2>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="Submit" value="Update"></input>
</form>
<form class="form-horizontal" action="/your_views/reset_password/" method="post">
{% csrf_token %}
<div class="form-group">
<div class="col-md-12">
<input type="password" placeholder="Old password" id="old_password" name="old_password" autocomplete="off" required class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="password" placeholder="New password" id="password1" name="password1" autocomplete="off" required class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="password" placeholder="Re-new password" id="password2" name="password2" autocomplete="off" required class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<button type="submit" class="btn btn-block btn-success" style="background: #00A79D;">Reset</button>
</div>
</div>
</form>
I implemented a method for Sign In with JWT and what it does is:
Fetches the email and password that is send with the request and
converts it into a string variable
I check if the email already
exists in the custom user model i made.
If the user already
exists, i convert the object model to dictionary so that i can get
its particular password.
In that i match the password
corresponding to user model and the password that is send with the
post request.
if the email exists in the user model and the password corresponding to that user model matches the password that is sent with the post request i use the pyJWT to make the JWT with my custom data and return the response.
In all other cases the email and password don't match and i return "No Match"
Suppose the request is {"email":"xyz#gmail.com", "password":"12345" }
#api_view(['POST'])
def signin(request):
email = list(request.data.values())[0] #gets email value from post request {"email":"xyz#gmail.com", "password":"123"} -> this xyz#gmail.com
password = list(request.data.values())[1] #gets password value from post request {"email":"xyz#gmail.com", "password":"123"} -> this 123
usr = User.objects.filter(email=email).exists() #checks if email exists
if usr:
dictionary = User.objects.filter(email=email).values()[0] #converts object to dictionary for accessing data like dictionary["password"] dictionary["first_name"] etc
if usr and dictionary["password"] == password: #check if email and its corresponing password stored matches the password that is sent
branch = dictionary["branch"]
id = dictionary["id"]
encoded_jwt = jwt.encode({'email': email,}, 'secret', algorithm='HS256')
return Response({'token':encoded_jwt,'email':email,'branch':branch,'id':id})
else:
return Response({'No Match'})
return Response({'No Match'})