Django实现用户名/邮箱登录遇问题,求代码修复方案
问题分析与修正方案
原代码的核心问题
- 缩进错误:Python对缩进要求严格,原代码多处缩进不一致,会直接触发语法错误。
- try-except完全误用:
User.objects.filter().first()查询不到用户时只会返回None,不会抛出异常,所以你的except分支永远不会执行,等于白写。 - authenticate不支持直接传email:Django默认的
authenticate方法只接受username参数,直接传email无效。 - 未处理验证失败的情况:如果用户不存在或密码错误,
user会是None,直接调用login会报错。 - 变量逻辑混乱:把同一个POST值同时赋值给
username和email,没有区分输入类型;context变量未定义就直接使用。
修正后的代码
from django.contrib.auth import authenticate, login from django.core.validators import validate_email from django.core.exceptions import ValidationError from django.shortcuts import render, redirect def login_attempt(request): context = {} if request.method == 'POST': # 获取用户输入的标识(可能是用户名或邮箱)和密码 identifier = request.POST.get('username').strip() password = request.POST.get('password').strip() user_obj = None # 先判断输入是否是邮箱格式 try: validate_email(identifier) # 是邮箱,按邮箱查用户 user_obj = User.objects.filter(email__iexact=identifier).first() except ValidationError: # 不是邮箱,按用户名查用户 user_obj = User.objects.filter(username__iexact=identifier).first() # 验证用户和密码 if user_obj: # 用查到的用户的用户名去验证密码 user = authenticate(username=user_obj.username, password=password) if user is not None: login(request, user) # 登录成功后跳转,比如跳转到首页 return redirect('home') else: context['error'] = '密码错误' else: context['error'] = '用户不存在' # GET请求或登录失败时返回登录页 return render(request, 'login.html', context)
关键说明
- 用
validate_email判断输入是否为邮箱,替代无效的try-except逻辑,精准区分查询路径。 - 使用
__iexact实现不区分大小写的查询(适配邮箱/用户名大小写不敏感的场景)。 - 先找到用户对象,再用其
username调用authenticate,符合Django默认验证规则。 - 增加错误提示反馈,登录成功后跳转至首页(可根据实际需求修改跳转目标)。
- 修复了缩进、变量未定义等基础语法问题。
内容的提问来源于stack exchange,提问作者Kokumi
相关产品推荐
相关产品推荐

