Django 访问当前登录用户个人主页报用户ID不存在异常的问题咨询
问题根因
当前异常的核心是自定义用户模型未和Django内置认证体系打通,出现两套独立用户表的ID错配:
- 你的项目没有将自己定义的
UserAccount设置为Django默认用户模型,@login_required装饰器、模板中request.user调用拿到的永远是Django自带auth.User表的对象,和你自己业务里新建的UserAccount表完全独立,两张表各自维护从1开始递增的独立主键。 - 你在模板中拼接个人主页链接时,取的
request.user.id是内置auth.User表的主键,和UserAccount表的主键没有映射关系:因为前期测试时两张表插入数据的顺序巧合,前几个用户的ID刚好对应,等新建第5个用户时,两边ID错位,就出现了“访问/account/5提示用户不存在,手动把URL改成/account/1却能展示当前登录用户信息”的诡异现象。
分步修复方案
配置项目默认用户模型
在项目根目录的settings.py中添加配置,让Django认证体系对接你自己写的用户表:AUTH_USER_MODEL = 'chat.UserAccount'注意:如果项目已经执行过初始化数据库迁移,需要先删除原有迁移文件、清空数据库中的迁移记录表,重新生成迁移文件并执行,否则会触发外键冲突报错。
修正
UserAccount模型定义
不要手动重复实现Django已经内置的认证字段,直接继承内置的抽象用户类,避免字段冗余和冲突,同时补上你视图中引用的缺失的profile_image字段:from django.contrib.auth.models import AbstractUser class UserAccount(AbstractUser): email = models.EmailField(verbose_name="email", max_length=60, unique=True) profile_image = models.ImageField(upload_to='profile_images', default='default_avatar.png') # 删掉重复定义的username、password、date_joined、last_login、is_superuser字段,父类已经完整实现这些能力 def __str__(self): return self.username优化
profile_view的取值逻辑
去掉冗余的对象判断分支,同时兼容查看他人主页、当前用户主页的场景,避免硬查参数导致的报错:@login_required(login_url='login') def profile_view(request, *args, **kwargs): user_id = kwargs.get("user_id") # 优先根据URL参数查询对应用户,无参数时直接返回当前登录用户 if user_id: try: profile = UserAccount.objects.get(pk=user_id) except UserAccount.DoesNotExist: return HttpResponse("User is not yet registered.") else: profile = request.user context = { 'id': profile.id, 'username': profile.username, 'profile_image': profile.profile_image, 'date_joined': profile.date_joined } return render(request, 'chat/profile.html', context)校验路由和模板的参数匹配
保持现有路由配置path('account/<user_id>/', views.profile_view, name='profile_view')不变,等自定义用户模型配置完成后,模板中原有拼接URL的代码{% url 'profile_view' user_id=request.user.id %}就能自动取到和数据库一致的用户主键,不会再出现ID错位的问题。
内容的提问来源于stack exchange,提问作者mango orange
相关产品推荐
相关产品推荐

