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

Django REST Framework无法创建多联系人及邮箱 迁移报错咨询

问题排查
  • 外键字段配置错误:Email模型的user_emails字段、PhoneNum模型的user_contacts字段仅设置了blank=True,未设置null=True。blank=True仅控制Django表单校验层面是否允许为空,数据库层面默认仍为非空约束,当数据库中已经存在Email/PhoneNum的历史数据时,新增/修改外键字段就会触发需要默认值的提示。
  • PhoneNum模型语法错误:__str__方法尝试返回self.phone_num,但实际字段名为contact_num,运行时会触发属性不存在报错。
  • 序列化器配置错误:MultipleSerializer的Meta.model参数同时传入了两个模型Email, PhoneNum,DRF的ModelSerializer仅支持绑定单个模型,该配置无法正常运行。
  • 序列化器字段不匹配:MultipleSerializer中定义的contacts字段,和PhoneNum模型的外键反向关联名contact_numbers不一致,无法正常读取关联数据。
解决方案

1. 修复模型字段配置

根据业务需求选择对应修改方案:

  • 方案A:如果允许邮箱/手机号不绑定联系人,修改外键字段补充null=True,同时修正PhoneNum的__str__方法:
# models.py 修正后代码
class Contact(models.Model):
    full_name = models.CharField(max_length=30, unique=True)
    nick_name = models.CharField(max_length=30, unique=True)
    status = models.BooleanField(default=1)

    def __str__(self):
        return self.full_name

    class Meta:
        ordering = ['full_name']

class Email(models.Model):
    email = models.EmailField(max_length=30)
    user_emails = models.ForeignKey(
        Contact, on_delete=models.CASCADE, related_name='emails', blank=True, null=True)

    def __str__(self):
        return self.email

class PhoneNum(models.Model):
    contact_num = models.CharField(max_length=30)
    user_contacts = models.ForeignKey(
        Contact, on_delete=models.CASCADE, related_name="contact_numbers", blank=True, null=True)

    def __str__(self):
        # 修正字段名引用错误
        return self.contact_num
  • 方案B:如果业务要求每个邮箱/手机号必须绑定一个联系人,不需要留空,可以直接删除项目中之前生成的未应用的迁移文件,同时清空测试数据库中Email、PhoneNum表的历史数据,不需要额外修改外键配置。

2. 修复序列化器配置

要实现查询联系人时同时返回关联的所有邮箱和手机号,直接修改ContactSerializer即可,无需单独定义MultipleSerializer:

# serializers.py 修正后代码
from django.db.models import fields
from rest_framework import serializers
from .models import Contact, Email, PhoneNum

class ContactSerializer(serializers.ModelSerializer):
    # 读取关联的邮箱和手机号列表
    emails = serializers.StringRelatedField(many=True, read_only=True)
    contact_numbers = serializers.StringRelatedField(many=True, read_only=True)
    class Meta:
        model = Contact
        fields = ['id', 'full_name', 'nick_name', 'status', 'emails', 'contact_numbers']

如果需要支持创建联系人时同时提交关联的邮箱和手机号,补充重写create方法即可。

3. 重新执行迁移

修复完成后,删除app/migrations/目录下除了__init__.py之外的所有迁移文件,依次执行以下命令即可完成迁移:

python manage.py makemigrations
python manage.py migrate

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:06:04