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'),  # 修改密码的路由
]

四、修改密码的模板

修改密码的模板与注册、登录的模板基本一致,不再贴出代码。

posted @ 2024-01-05 15:54  喜气洋洋白云山  阅读(191)  评论(0编辑  收藏  举报