Django会话、登录与注册功能异常:登录后无法跳转至主页
1. 视图函数名与Django内置函数冲突
你的login视图函数内部调用了login(request, user),但此时的login是你自己定义的视图函数,而非Django官方的django.contrib.auth.login认证函数。这会导致用户登录逻辑根本无法正确执行,会话未建立,后续跳转自然失效。
修复方案:
要么给内置登录函数取别名,要么重命名你的视图函数:
# 导入时给内置login取别名 from django.contrib.auth import login as auth_login # 重命名视图函数避免冲突 def user_login(request): if request.method == 'GET': return render(request, 'registration/login.html') if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') user = authenticate(request, username=username, password=password) if user is not None and user.is_active: auth_login(request, user) # 使用别名后的内置认证函数 return redirect('user_home') else: # 新增错误提示,让用户知晓登录失败原因 return render(request, 'registration/login.html', {'error': '用户名或密码错误'})
同时记得在urls.py中把原login路径改为user_login,并确保user_home的URL名称配置正确。
2. user_home视图仅处理POST请求
登录后通过redirect('user_home')发起的是GET请求,但你的user_home视图只编写了POST分支的逻辑。当GET请求进入时,视图没有返回任何响应,Django会默认返回405 Method Not Allowed状态码,导致页面无法正常跳转。
修复方案:
调整视图逻辑,支持GET请求,同时利用Django auth系统直接获取用户信息:
from django.contrib.auth.decorators import login_required # 取消注释装饰器,强制只有登录用户才能访问 @login_required def user_home(request): # 直接从request.user获取当前登录用户信息,无需手动操作session context = { 'username': request.user.username } return render(request, 'rescues_site/home_page.html', context)
3. sign_up视图缺失异常处理分支
你的sign_up视图中try块没有对应的except语句,若创建CustomUser时出现错误(如邮箱重复、字段验证失败),会直接抛出异常中断请求,无法执行到跳转逻辑。
修复方案:
添加异常捕获分支,返回注册页面并提示错误:
from django.db import IntegrityError @transaction.atomic def sign_up(request): if request.method == 'GET': return render(request, 'registration/sign_up.html') if request.method == 'POST': errors = [] first_name = request.POST.get('first_name') last_name = request.POST.get('last_name') address = request.POST.get('address') suburb = request.POST.get('suburb') postcode = request.POST.get('postcode') email = request.POST.get('email') phone_number = request.POST.get('phone_number', None) password = make_password(request.POST.get('password')) try: user = CustomUser.objects.create( username=email, first_name=first_name, last_name=last_name, address=address, suburb=suburb, postcode=postcode, phone_number=phone_number, password=password ) auth_login(request, user) # 注册后直接完成登录 return redirect('user_home') except IntegrityError: errors.append('该邮箱已被注册') return render(request, 'registration/sign_up.html', {'errors': errors}) except Exception as e: errors.append(f'注册失败:{str(e)}') return render(request, 'registration/sign_up.html', {'errors': errors})
4. 冗余的Session存储操作
你手动将username存入session的操作完全多余,Django的auth系统通过auth_login函数已自动建立用户会话。在任何登录后的视图中,都可以通过request.user直接获取当前用户的所有信息(如request.user.username、request.user.first_name等)。
内容的提问来源于stack exchange,提问作者Khiết Huỳnh

