|
|
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') |