Django注册加用户到Group、登录校验所属用户组问题求助
注册功能修复
错误原因
- Django模型实例的
save()方法默认返回None,原代码将myuser.save()的返回值赋值给stuser后调用stuser.groups,自然触发NoneType无属性报错 User.objects.create_user已经自动完成密码哈希存储,原代码后续手动赋值myuser.password = pass1会把明文密码覆盖写入数据库,直接导致后续登录校验失败- Django默认User模型无
name字段,传入的username已经是用户名,不需要额外赋值myuser.name
修正后的注册视图代码
def stusignup(request): if request.method == "POST": name = request.POST['name'] email = request.POST['email'] pass1 = request.POST['password1'] pass2 = request.POST['password2'] if pass1 != pass2: messages.error(request,"两次输入的密码不一致!") else: # create_user已经自动完成用户存储、密码哈希,不需要额外调用save myuser = User.objects.create_user(username=name, password=pass1, email=email) # 直接用myuser实例操作用户组即可 group = Group.objects.get(name='Student') myuser.groups.add(group) return redirect('studentloginpage') return render(request,'stusignup.html')
登录功能修复
错误原因
- 不能直接用明文密码查询数据库:Django存储的是哈希后的密码,明文查询永远匹配不到用户
- 逻辑顺序错误:原代码先查询用户再判断是否为None,
get方法查询不到会直接抛出DoesNotExist异常,不会返回None - 未做异常捕获:用户输入错误账号密码时会直接报错,而不是返回友好提示
修正后的登录视图代码
from django.contrib import auth def stuloginpage(request): if request.method == 'POST': user_email = request.POST['email'] pass1 = request.POST['password'] # 先校验邮箱是否存在 user_query = User.objects.filter(email=user_email).first() if not user_query: messages.info(request, "用户名或密码错误") return render(request, 'stulogin.html') # 用Django自带方法校验密码正确性 user = auth.authenticate(request, username=user_query.username, password=pass1) if user is not None: # 密码校验通过后再判断用户组 if user.groups.filter(name='Student').exists(): login(request, user) return redirect('homepage') else: return HttpResponse("您不属于学生用户组,无法登录!") else: messages.info(request, "用户名或密码错误") return render(request, 'stulogin.html')
分组校验装饰器修复
错误原因
原is_student函数返回的是QuerySet对象,不是布尔值,装饰器判断时会永远认为校验不通过,需要添加.exists()返回布尔结果
修正后的装饰器代码
def is_student(user): # 同时校验用户已登录且属于Student组 return user.is_authenticated and user.groups.filter(name='Student').exists() # 直接在需要学生权限的视图上添加装饰器即可 @user_passes_test(is_student, login_url='studentloginpage') def student_only_view(request): # 仅学生组用户可访问 return render(request, 'student_page.html')
前置注意事项
- 提前创建好
Student用户组,可以通过Django admin后台手动添加,或者编写数据迁移脚本自动创建 - 如果你使用的是自定义User模型,调整邮箱、用户名字段的对应查询逻辑即可
内容的提问来源于stack exchange,提问作者Dcoder
相关产品推荐
相关产品推荐

