You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DjangoBlog/accounts/views.py

218 lines
9.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import CustomUserCreationForm, CustomUserChangeForm
from django.contrib import messages
from django.contrib.auth import get_user_model
from .email_service import EmailService
def register(request):
"""用户注册视图"""
# MYT检查请求方法是否为POST即用户提交注册表单
if request.method == 'POST':
# MYT使用用户提交的数据和文件初始化注册表单
form = CustomUserCreationForm(request.POST, request.FILES)
# MYT验证表单数据是否有效
if form.is_valid():
# MYT保存表单数据创建新用户
user = form.save()
# MYT自动登录新创建的用户
login(request, user)
# MYT显示成功注册消息
messages.success(request, '注册成功!欢迎来到金陵非遗。')
# MYT获取重定向URL如果没有则默认到首页
next_url = request.GET.get('next', 'index')
return redirect(next_url)
else:
# MYT如果是GET请求创建空表单实例
form = CustomUserCreationForm()
# MYT渲染注册页面并传递表单对象
return render(request, 'accounts/register.html', {'form': form})
def user_login(request):
"""用户登录视图"""
# MYT检查请求方法是否为POST即用户提交登录表单
if request.method == 'POST':
# MYT使用请求数据和用户提交的数据初始化登录表单
form = AuthenticationForm(request, data=request.POST)
# MYT验证表单数据是否有效
if form.is_valid():
# MYT从验证后的表单数据中获取用户名
username = form.cleaned_data.get('username')
# MYT从验证后的表单数据中获取密码
password = form.cleaned_data.get('password')
# MYT验证用户凭据是否正确
user = authenticate(username=username, password=password)
# MYT检查用户是否存在且有效
if user is not None:
# MYT登录用户并建立会话
login(request, user)
# MYT显示欢迎登录消息
messages.success(request, f'欢迎回来,{username}')
# MYT获取重定向URL如果没有则默认到首页
next_url = request.GET.get('next', 'index')
return redirect(next_url)
else:
# MYT如果表单验证失败显示错误消息
messages.error(request, '用户名或密码错误,请重试。')
else:
# MYT如果是GET请求创建空登录表单实例
form = AuthenticationForm()
# MYT渲染登录页面并传递表单对象
return render(request, 'accounts/login.html', {'form': form})
@login_required
def profile(request):
"""用户个人资料页面"""
# MYT渲染用户个人资料页面传递当前用户对象
return render(request, 'accounts/profile.html', {'user': request.user})
@login_required
def profile_edit(request):
"""编辑用户资料"""
# MYT检查请求方法是否为POST即用户提交编辑表单
if request.method == 'POST':
# MYT使用用户提交的数据和当前用户实例初始化编辑表单
form = CustomUserChangeForm(request.POST, request.FILES, instance=request.user)
# MYT验证表单数据是否有效
if form.is_valid():
# MYT保存表单数据更新用户信息
form.save()
# MYT显示更新成功消息
messages.success(request, '资料更新成功!')
# MYT重定向到个人资料页面
return redirect('profile')
else:
# MYT如果是GET请求使用当前用户数据预填充表单
form = CustomUserChangeForm(instance=request.user)
# MYT渲染资料编辑页面并传递表单对象
return render(request, 'accounts/profile_edit.html', {'form': form})
def password_reset_request(request):
"""密码重置请求 - 发送验证码"""
# MYT检查请求方法是否为POST即用户提交重置请求
if request.method == 'POST':
# MYT从POST数据中获取邮箱地址
email = request.POST.get('email')
# MYT检查邮箱是否为空
if not email:
messages.error(request, '请输入邮箱地址')
return render(request, 'accounts/password_reset_request.html')
# MYT获取用户模型类
User = get_user_model()
try:
# MYT根据邮箱查找用户是否存在
user = User.objects.get(email=email)
except User.DoesNotExist:
# MYT如果用户不存在显示错误消息
messages.error(request, '该邮箱未注册')
return render(request, 'accounts/password_reset_request.html')
# MYT调用邮箱服务发送验证码
success, message = EmailService.send_verification_code(email)
# MYT检查验证码是否发送成功
if success:
# MYT将重置邮箱存入session供后续步骤使用
request.session['reset_email'] = email
# MYT显示发送成功消息
messages.success(request, message)
# MYT重定向到验证码验证页面
return redirect('password_reset_verify')
else:
# MYT如果发送失败显示错误消息
messages.error(request, message)
# MYT渲染密码重置请求页面
return render(request, 'accounts/password_reset_request.html')
def password_reset_verify(request):
"""验证邮箱验证码"""
# MYT从session中获取之前存储的重置邮箱
email = request.session.get('reset_email')
# MYT检查邮箱是否存在防止直接访问此页面
if not email:
messages.error(request, '请先请求密码重置')
return redirect('password_reset_request')
# MYT检查请求方法是否为POST即用户提交验证码
if request.method == 'POST':
# MYT从POST数据中获取用户输入的验证码
verification_code = request.POST.get('verification_code')
# MYT验证邮箱和验证码是否匹配
if EmailService.verify_code(email, verification_code):
# MYT验证成功在session中标记已验证状态
request.session['verified'] = True
# MYT显示验证成功消息
messages.success(request, '验证成功,请设置新密码')
# MYT重定向到密码确认页面
return redirect('password_reset_confirm')
else:
# MYT验证失败显示错误消息
messages.error(request, '验证码错误或已过期')
# MYT渲染验证码验证页面传递邮箱信息
return render(request, 'accounts/password_reset_verify.html', {'email': email})
def password_reset_confirm(request):
"""设置新密码"""
# MYT从session中获取重置邮箱和验证状态
email = request.session.get('reset_email')
verified = request.session.get('verified')
# MYT检查是否已完成前面的验证步骤
if not email or not verified:
messages.error(request, '请先完成验证')
return redirect('password_reset_request')
# MYT检查请求方法是否为POST即用户提交新密码
if request.method == 'POST':
# MYT从POST数据中获取新密码
new_password = request.POST.get('new_password')
# MYT从POST数据中获取确认密码
confirm_password = request.POST.get('confirm_password')
# MYT检查密码是否为空
if not new_password or not confirm_password:
messages.error(request, '请输入密码')
# MYT检查两次输入的密码是否一致
elif new_password != confirm_password:
messages.error(request, '两次输入的密码不一致')
# MYT检查密码长度是否符合要求
elif len(new_password) < 8:
messages.error(request, '密码长度至少8位')
else:
# MYT获取用户模型类
User = get_user_model()
try:
# MYT根据邮箱查找用户
user = User.objects.get(email=email)
# MYT设置新密码会自动加密
user.set_password(new_password)
# MYT保存用户信息
user.save()
# MYT清理session中的重置相关数据
request.session.pop('reset_email', None)
request.session.pop('verified', None)
# MYT显示密码重置成功消息
messages.success(request, '密码重置成功,请使用新密码登录')
# MYT重定向到重置完成页面
return redirect('password_reset_complete')
except User.DoesNotExist:
# MYT如果用户不存在显示错误消息
messages.error(request, '用户不存在')
# MYT渲染密码重置确认页面
return render(request, 'accounts/password_reset_confirm.html')
def password_reset_complete(request):
"""密码重置完成页面"""
# MYT渲染密码重置完成页面
return render(request, 'accounts/password_reset_complete.html')