Django登录功能报错:'QuerySet' object has no attribute 'startswith'
问题分析与修复方案
你的登录验证报错'QuerySet' object has no attribute 'startswith',以及后续可能的密码验证失败,根源在两个地方:
1. 密码字段长度不足
你的User模型中user_password字段设置了max_length=20,但make_password()生成的哈希密码长度远超过20位,会被数据库截断,导致存储的哈希值不完整,后续验证必然失败。
2. 登录逻辑错误
你传给check_password()的第二个参数是QuerySet(User.objects.filter(...)返回的查询集合),但这个函数需要的是字符串类型的哈希密码,所以触发了类型错误。同时原本的逻辑完全没做密码验证,只要邮箱存在就直接登录,这是严重的安全问题。
第一步:修复模型的密码字段
修改user_password的长度为至少128位(Django默认密码字段长度):
class User(models.Model): user_email = models.CharField(primary_key=True, max_length=100) user_role_id = models.CharField(max_length=20) # 调整长度以容纳完整的哈希密码 user_password = models.CharField(max_length=128) user_name = models.CharField(max_length=100) user_avatar_path = models.CharField(max_length=300) user_job_title = models.TextField(blank=True, null=True) user_educ_qual = models.TextField(blank=True, null=True) user_companies = models.TextField(blank=True, null=True) class Meta: managed = False db_table = 'user'
注意:因为设置了
managed=False,修改模型后需要手动去数据库修改对应字段的长度,否则依然会截断哈希密码。
第二步:修复登录视图逻辑
重新梳理验证流程,先通过邮箱找到用户,再验证密码:
def user_login(request): if request.method == "POST": user_email = request.POST['user_email'] user_password = request.POST['user_password'] try: # 邮箱是主键,用get()获取单个用户对象 user = User.objects.get(user_email=user_email) except User.DoesNotExist: # 邮箱不存在,返回错误提示 return render(request, 'EmpLogin.html', {'msg': "邮箱或密码错误"}) # 用用户存储的哈希密码验证输入的明文密码 if check_password(user_password, user.user_password): # 验证通过,设置会话信息 request.session['logged_in'] = True request.session['user_email'] = user.user_email request.session['u_id'] = user.user_email request.session['user_name'] = user.user_name request.session['u_type'] = "emp" return HttpResponseRedirect('/user_index') else: # 密码错误,返回提示 return render(request, 'EmpLogin.html', {'msg': "邮箱或密码错误"}) else: return render(request, 'EmpLogin.html')
关键修改说明
- 用
get()替代filter():因为邮箱是主键,确保返回单个用户对象,而非查询集合 - 正确传递参数给
check_password():第二个参数是用户对象的user_password属性(字符串类型的哈希值) - 增加异常捕获:处理邮箱不存在的情况,避免程序崩溃
- 先验证密码再登录:只有密码验证通过后,才设置会话并跳转,修复了原逻辑的安全漏洞
内容的提问来源于stack exchange,提问作者JHS99
相关产品推荐
相关产品推荐

