django练手(十四):实现网站用户修改密码的功能
一、修改密码的Form。
思路:
1、定义三个输入框,分别是老密码,新密码,重复密码。
2、重写Form的__init__方法,加入request参数,以便验证数据有效性的时候把request传进来。
3、利用request,获取数据库中保存的密码,并与老密码校验。如果结果为False,提示错误,老密码输入不正确。
4、获取新密码,校验新密码的位数,不符合提示错误。
5、校验重复密码,新密码。如果重复密码与新密码不一致,提示错误。如果新密码与老密码相同,提示密码没有更改。
代码如下:
class ChangePassword(forms.Form):
old_password = forms.CharField(widget=forms.PasswordInput, required=True, label='原密码', min_length=8,
max_length=25,
error_messages={'required': '密码不能为空', 'min_length': '密码长度介于8-25位',
'max_length': '密码长度介于8-25位'})
new_password = forms.CharField(widget=forms.PasswordInput, required=True, label='新密码', min_length=8,
max_length=25,
error_messages={'required': '密码不能为空', 'min_length': '密码长度介于8-25位',
'max_length': '密码长度介于8-25位'})
confirm_new_password = forms.CharField(widget=forms.PasswordInput, required=True, label='新密码', min_length=8,
max_length=25,
error_messages={'required': '密码不能为空',
'min_length': '密码长度介于8-25位',
'max_length': '密码长度介于8-25位'})
# 修改父类的__init__方法,实现可以从视图获取request。同时,给表单增加bootstrap样式
def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
self.request = request
# 给表单加上bootstrap的样式
for name, field in self.fields.items():
field.widget.attrs['class'] = "form-control"
field.widget.attrs['placeholder'] = '请输入{}'.format(field.label)
def clean_old_password(self):
# 获取用户输入的密码(未加密)
old_password = self.cleaned_data['old_password']
# 获取当前用户的密码(已加密)
password = self.request.user.password
# 使用auth组件,hashers下的check_password方法,可以验证加密后的密码与未加密的密码是否相同
if not check_password(old_password, password):
raise ValidationError('原密码输入不正确,请重新输入')
return old_password
def clean_new_password(self):
new_password = self.cleaned_data['new_password']
if len(new_password) > 20 or len(new_password) < 7:
raise ValidationError('密码不能小于8位或大于20位')
return new_password
def clean_confirm_new_password(self):
confirm_new_password = self.cleaned_data['confirm_new_password']
new_password = self.cleaned_data.get('new_password', '')
old_password = self.cleaned_data.get('old_password', '')
if confirm_new_password != new_password:
raise ValidationError('两次输入密码不一致')
if new_password == old_password:
raise ValidationError('密码没有更改,请重新输入')
return confirm_new_password
二、修改密码的View。
代码如下:
def change_password(request):
if request.method == 'GET':
fields = ChangePassword(request)
return render(request, 'app/change_password.html', {'fields': fields})
if request.method == 'POST':
data = request.POST
fields = ChangePassword(request, data)
if fields.is_valid():
# 获取清洗过的新密码
new_password = fields.cleaned_data.get('new_password', '')
# 获取当前用户
user = request.user
# 用新密码修改当前用户的密码
user.set_password(new_password)
# 保存当前用户
user.save()
# 当前用户重新登录
login(request, user)
return JsonResponse({'status':True})
else:
return JsonResponse({'status':False,'errors':fields.errors})
三、修改密码的路由。
代码如下:
from django.urls import path
from app.views.app.views import *
urlpatterns = [
path('register/', register, name='register'), # 注册的路由
path('login/', login_view, name='login'), # 登录的路由
path('logout/', auth_logout, name='logout'), # 注销的路由
path('changepwd/', change_password, name='change_password'), # 修改密码的路由
]
四、修改密码的模板
修改密码的模板与注册、登录的模板基本一致,不再贴出代码。