You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django自引用多对多关系场景下无法正确获取关联数据如何解决

问题原因
  • 关联属性调用错误:to_person是Relationship模型中指向被关注用户的外键的反向关联,代表的是所有关注当前用户的关联记录,你在当前用户对象上直接调用self.to_person拿到的是反向关系管理器,根本不是你要的当前用户关注的其他人列表,所以输出为空。
  • get_all_followings方法没有设置返回值,视图中拿到的all_followings默认就是None。
  • 自关联多对多字段未指定through_fields:自关联场景下使用中间表必须指定through_fields明确字段对应关系,否则多对多的方向会异常。
  • 额外错误:你自定义了password字段覆盖了AbstractUser自带的密码字段,设置的max_length=15远小于Django加密后密码的长度,会导致密码存储失败,后续登录逻辑会直接报错。
解决步骤
  1. 修正CustomUser模型的定义,补全多对多字段参数,删除多余的自定义password字段:
class CustomUser(AbstractUser):
    email = models.EmailField(max_length=250, null=False, unique=True)
    name = models.CharField(max_length=50, null=False)
    username = models.CharField(max_length=50, null=False)
    # 删掉自定义的password字段,用父类自带的即可
    # 补全through_fields参数,第一个是源模型对应的外键,第二个是目标模型对应的外键
    # 字段名改为following语义更清晰,避免混淆
    following = models.ManyToManyField('self', through='Relationship', symmetrical=False, related_name='followers', through_fields=('from_person', 'to_person'))

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name', 'username']

    def get_all_followings(self):
        # 直接通过多对多字段拿到所有关注的用户
        return self.following.all()
  1. 修正视图代码,拿到关注列表后传入模板:
def see_all_followings(request):
    if request.method == 'GET':
        # request.user本身就是CustomUser实例,不需要额外查库
        all_followings = request.user.get_all_followings()
        return render(request, "all_followings.html", {'users': all_followings, 'is_follow': True})
  1. 执行迁移命令更新数据库结构:
python manage.py makemigrations
python manage.py migrate

如果之前已经有错误的迁移记录,需要先清空对应app的migrations文件夹下除了__init__.py之外的文件,再重新生成迁移。

内容的提问来源于stack exchange,提问作者Atharva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 01:54:02