Django一对一关联模型报错:Field 'id'期望数字却获空值
Django 一对一关联模型报错解决:ValueError: Field 'id' expected a number but got ' '
问题根源分析
你遇到的报错核心是模型主键修改后旧迁移/表结构残留冲突,再加上字段默认值设置不规范,导致Django处理字段默认值时出现类型不匹配:
- 你将
userInfo的主键改为字符串类型的Username,并把rentDetails的主键设为关联该模型的一对一字段,但旧迁移或数据库表中可能还残留着原来默认的整数类型id主键引用 - 多个字段的默认值设置错误:比如CharField用
default=True(布尔值会被转成字符串"True",不符合字段类型预期),IntegerField用default=True虽能转成1,但不符合规范;property_type未设置默认值也未允许为空,后续创建数据必报错
修复步骤
1. 修正模型字段定义(符合规范+修复默认值)
按照Django命名规范(类名大驼峰、字段名小写下划线)修正后的models.py:
from django.db import models class UserInfo(models.Model): username = models.CharField(max_length=100, primary_key=True) password = models.CharField(max_length=100) def __str__(self): return self.username class RentDetails(models.Model): user = models.OneToOneField( UserInfo, on_delete=models.CASCADE, primary_key=True ) floor_no = models.CharField(max_length=20, default="1") # CharField用字符串默认值 distance = models.IntegerField(default=0) # IntegerField用数字默认值 location = models.CharField(max_length=200, default="") area = models.IntegerField(default=0) no_of_rooms = models.IntegerField(default=1) price = models.IntegerField(default=0) property_choices = [ ('hostel','Hostel'), ('house','House'), ('room','Room'), ('flat','Flat') ] property_type = models.CharField( max_length=10, choices=property_choices, default="room" # 添加默认值避免必填报错 ) images = models.ImageField(upload_to='uploads/', null=True, blank=True) # blank=True方便表单提交
2. 清理旧迁移并重新生成
由于修改了主键结构,旧迁移文件大概率存在冲突,需要彻底清理后重新生成:
- 备份数据库(重要!防止数据丢失)
- 删除你的app目录下
migrations文件夹中除__init__.py外的所有文件 - 清空PostgreSQL中对应的数据库表(或直接删除数据库后重新创建)
- 重新执行迁移命令:
python manage.py makemigrations python manage.py migrate
额外提示
- 新手尽量避免一开始就自定义主键,先使用Django默认的自增整数
id主键,熟悉框架后再根据业务需求调整 - 字段默认值要严格匹配字段类型,避免布尔值与字符串/数字混用
内容的提问来源于stack exchange,提问作者jen
相关产品推荐
相关产品推荐

