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

Django迁移报错:外键关联非默认主键User模型时出现完整性错误

问题描述

尝试用ForeignKey关联未使用默认主键的User模型,通过属性获取该模型的usertag,但执行迁移时出现错误:

django.db.utils.IntegrityError: 表'user_friend'中主键为'LOL'的行存在无效外键:user_friend.fk_id的值'fk_id'在user_user.id中无对应值。

对应的models.py代码:

from django.db import models

class User(models.Model):
    f_name = models.CharField(max_length=15)
    l_name = models.CharField(max_length=15)
    usertag = models.CharField(max_length=7, default="aabb11")
    level = models.IntegerField(default=1)
    profile_pic = models.URLField(max_length=10000)
    email = models.EmailField(max_length=100)
    password = models.CharField(max_length=25)


class invites(models.Model):
    invite_id = models.CharField(max_length=8, primary_key=True)
    choices = [("P", "PENDING"), ("A", "ACCEPTED"), ("D", "DECLINED")]
    sent_to = models.CharField(max_length=7) 
    from_user = models.CharField(max_length=7) 
    invite_status = models.CharField(choices=choices, default=choices[0], max_length=9)


# USE Foreign KEYS
class friend(models.Model):
    fk = models.ForeignKey(User, on_delete=models.CASCADE, db_constraint=False)
    friend_tag = models.CharField(max_length=7, primary_key=True)

    @property
    def my_tag(self):
        return self.fk.usertag
解决方案

核心问题分析

  1. 你想基于User模型的usertag字段做外键关联,但Django默认会用模型的主键(这里User没显式指定主键,Django自动生成了自增id字段)作为外键关联目标,而非usertag。
  2. user_friend表中存在旧数据,其中fk_id字段的部分值(比如错误里的'fk_id')在user_user表的id字段中无对应记录,触发完整性校验失败。

具体修复步骤

1. 调整外键关联目标字段

如果业务逻辑是让friend.fk关联User.usertag,需显式指定to_field参数,同时给usertag添加唯一约束(外键关联的字段必须唯一):

class User(models.Model):
    # 给usertag添加唯一约束,确保可作为外键目标
    usertag = models.CharField(max_length=7, default="aabb11", unique=True)
    f_name = models.CharField(max_length=15)
    l_name = models.CharField(max_length=15)
    level = models.IntegerField(default=1)
    profile_pic = models.URLField(max_length=10000)
    email = models.EmailField(max_length=100)
    password = models.CharField(max_length=25)

class friend(models.Model):
    # 显式指定关联User的usertag字段
    fk = models.ForeignKey(User, on_delete=models.CASCADE, to_field='usertag', db_constraint=False)
    friend_tag = models.CharField(max_length=7, primary_key=True)

    @property
    def my_tag(self):
        return self.fk.usertag

2. 清理或修正旧数据

迁移前处理user_friend表的无效数据:

  • 删除fk_id字段无对应User记录的行
  • 或把无效的fk_id值修正为User表中存在的usertag值
  • 开发环境可直接清空user_friend表

3. 重新执行迁移

修改模型后,重新生成并执行迁移:

python manage.py makemigrations
python manage.py migrate

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 12:50:53