Django自定义Jobseeker模型登录后导航栏无法显示正确用户名
问题
自定义Jobseeker模型替代Django内置User做用户认证,实现了用户名/邮箱登录逻辑,但导航栏使用{{request.user}}时,显示的是超级用户而非当前登录的Jobseeker用户,需要显示登录的用户名。
问题原因
- Django的
auth.login()和request.user默认绑定内置User模型,你的Jobseeker未继承认证相关基类,也没配置自定义认证后端,所以auth.authenticate无法识别Jobseeker实例,request.user始终是默认的匿名用户或后台登录的超级用户。 - 现有登录逻辑存在错误:
if Jobseeker is not None是判断模型类而非实例jobseeker;找到邮箱对应的用户名后未做密码验证;依赖auth.authenticate处理自定义模型的认证逻辑无效。
解决方案
1. 修复登录视图逻辑
放弃使用auth模块的authenticate和login,改为手动验证并通过session存储用户信息:
def login(request): if request.method == 'POST': userinput = request.POST['username'] password_input = request.POST['password'] jobseeker = None # 优先通过邮箱匹配用户 try: jobseeker = Jobseeker.objects.get(email=userinput) except Jobseeker.DoesNotExist: # 邮箱匹配失败,尝试用户名匹配 try: jobseeker = Jobseeker.objects.get(username=userinput) except Jobseeker.DoesNotExist: pass # 验证密码(注意:当前是明文验证,后续需优化为哈希验证) if jobseeker and jobseeker.password == password_input: # 将用户ID存入session,标记登录状态 request.session['jobseeker_id'] = jobseeker.id messages.success(request, "登录成功") return redirect('home') else: messages.error(request, '无效的凭据,请检查用户名/邮箱或密码。') return render(request, 'login.html')
2. 自定义上下文处理器,让模板获取当前登录用户
在你的app目录下创建context_processors.py文件,添加以下代码:
from .models import Jobseeker def current_jobseeker(request): # 从session中获取用户ID jobseeker_id = request.session.get('jobseeker_id') if jobseeker_id: try: # 返回当前登录的Jobseeker实例 return {'current_jobseeker': Jobseeker.objects.get(id=jobseeker_id)} except Jobseeker.DoesNotExist: # 用户不存在时清除无效session del request.session['jobseeker_id'] # 未登录时返回None return {'current_jobseeker': None}
然后在项目的settings.py中,找到TEMPLATES配置,在OPTIONS的context_processors列表里添加上下文处理器路径(替换yourapp为你的app名称):
TEMPLATES = [ { # ... 其他配置 'OPTIONS': { 'context_processors': [ # ... 原有处理器 'yourapp.context_processors.current_jobseeker', ], }, }, ]
3. 模板中使用自定义用户变量
修改导航栏模板,替换{{request.user}}为{{ current_jobseeker.username }},同时可添加登录状态判断:
{% if current_jobseeker %} <span>欢迎,{{ current_jobseeker.username }}</span> <a href="{% url 'logout' %}">登出</a> {% else %} <a href="{% url 'login' %}">登录</a> {% endif %}
4. 密码安全优化(必做)
当前模型中密码以明文存储,存在严重安全隐患,需改为哈希存储:
修改Jobseeker模型:
from django.contrib.auth.hashers import make_password, check_password class Jobseeker(models.Model): username = models.CharField(max_length=50, unique=True) email = models.CharField(max_length=50, unique=True) # 哈希密码长度较长,调整字段长度 password = models.CharField(max_length=128) # 移除repassword字段,该字段仅用于注册时验证,无需存入数据库 def save(self, *args, **kwargs): # 新增或修改密码时自动哈希 if not self.pk or self.password != Jobseeker.objects.get(pk=self.pk).password: self.password = make_password(self.password) super().save(*args, **kwargs) def check_password(self, raw_password): # 提供密码验证方法 return check_password(raw_password, self.password) def __str__(self): return self.username
更新登录视图的密码验证逻辑:
将原来的jobseeker.password == password_input替换为:
if jobseeker and jobseeker.check_password(password_input):
5. 实现登出功能
添加登出视图,清除session中的用户信息:
def logout(request): # 清除所有session数据 request.session.flush() messages.success(request, "已成功登出") return redirect('home')
记得在urls.py中配置登出路由。
内容的提问来源于stack exchange,提问作者Selfcontrol31
相关产品推荐
相关产品推荐

