Django用户注册时如何将邮箱转为小写并实现自动登录?
问题分析与解决
你的代码里有两个关键问题导致注册后无法自动登录:
1. 用户对象未实际保存到数据库
在处理推荐注册的分支中,你写了instance.save,这里缺少括号(),导致用户对象并未被真正保存到数据库。后续依赖该用户的操作都会出现异常,直接影响登录流程。
2. 认证时使用了原始大小写的邮箱
你将数据库中的邮箱转换为小写,但认证时用的是form.cleaned_data.get('email')获取的用户原始输入(可能包含大写)。Django的authenticate默认会严格匹配用户名/邮箱的大小写,这就导致数据库里的小写邮箱和输入的原邮箱无法匹配,认证失败。
修正后的完整代码
def registerRef(request, *args, **kwargs): if request.user.is_authenticated: return redirect('core:index') profile_id = request.session.get('ref_profile') print('profile_id', profile_id) try: signup_point = SignUpPoint.objects.get() except: signup_point = None code = str(kwargs.get('ref_code')) try: profile = Profile.objects.get(code=code) profile_user = Profile.objects.get(code=code) request.session['ref_profile'] = profile.id print('Referer Profile:', profile.id) except: pass print("Session Expiry Date:" + str(request.session.get_expiry_age())) form = UserRegisterForm(request.POST or None) if form.is_valid(): if profile_id is not None: recommended_by_profile = Profile.objects.get(id=profile_id) ref_earn = InvestmentPackageID.objects.get() instance = form.save(commit=False) # 转换邮箱和用户名到小写 instance.email = instance.email.lower() instance.username = instance.username.lower() # 修复:添加括号执行保存操作 instance.save() # 直接使用已保存的instance,避免重复查询数据库 registered_user = instance registered_profile = Profile.objects.get(user=registered_user) registered_profile.recommended_by = recommended_by_profile.user my_recomended = Profile.objects.filter(recommended_by=profile_user.user).values_list('user__id', flat=True) print(my_recomended) registered_profile.save() profile = Profile.objects.get(user=registered_user) profile.earning_point = signup_point.signup_point profile.main_all_earning += signup_point.signup_point profile.save() # 简化条件判断写法 if recommended_by_profile.level_1 and not recommended_by_profile.level_6 and not recommended_by_profile.level_5 and not recommended_by_profile.level_4 and not recommended_by_profile.level_3 and not recommended_by_profile.level_2: recommended_by_profile.referral_point += ref_earn.ref_earn1 recommended_by_profile.main_all_earning += ref_earn.ref_earn1 recommended_by_profile.save() else: recommended_by_profile.referral_point += 500 recommended_by_profile.main_all_earning += 500 recommended_by_profile.save() ActiveRefEarning.objects.create(user=registered_user, active_ref_earning_owner=recommended_by_profile.user, active_ref_earning=500) profile.save() recommended_by_profile.save() else: # 非推荐注册分支也统一转换邮箱和用户名到小写 instance = form.save(commit=False) instance.email = instance.email.lower() instance.username = instance.username.lower() instance.save() registered_user = instance profile = Profile.objects.get(user=registered_user) profile.earning_point = signup_point.signup_point profile.main_all_earning += signup_point.signup_point profile.save() # 修复:使用数据库中存储的小写邮箱进行认证 username = registered_user.email password = form.cleaned_data.get('password1') user = authenticate(username=username, password=password) # 添加认证成功判断,避免异常 if user is not None: login(request, user) NewsLetter.objects.create(email=username) messages.success(request, f"Hi {request.user.username}, {signup_point.signup_message}") return redirect('core:index') context = {'form':form} return render(request, 'userauths/sign-up.html', context)
额外优化说明
- 统一两个分支的处理逻辑,非推荐注册分支也转换邮箱和用户名到小写,保持数据一致性
- 直接使用保存后的
instance作为registered_user,减少不必要的数据库查询 - 简化条件判断语句,提升代码可读性
- 添加
user is not None的判断,避免认证失败时调用login抛出异常
内容的提问来源于stack exchange,提问作者Destiny Franks
相关产品推荐
相关产品推荐

