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
解决方案
核心问题分析
- 你想基于
User模型的usertag字段做外键关联,但Django默认会用模型的主键(这里User没显式指定主键,Django自动生成了自增id字段)作为外键关联目标,而非usertag。 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
相关产品推荐
相关产品推荐

