Django迁移报外键约束错误但关联对象实际存在,问题出在哪?
问题根因
你触发异常的直接原因是多对多字段add()方法的传参错误:
- 你的代码里
sy_collections是已经筛选好的ShopifyCollection对象列表,而add()方法要求传入多个独立的对象参数,而非直接传入列表对象。你直接传入sy_collections时,Django会把整个列表作为单个参数处理,试图将列表的字符串表示(就是你报错里看到的[<ShopifyCollection: ShopifyCollection object (gid://shopify/Collection/263596736569)>])作为外键值写入中间表,自然触发外键约束校验失败。 - 修复方式很简单,给列表加解包符即可,把
design.shopify_category.add(sy_collections)改成design.shopify_category.add(*sy_collections)。
另外需要修正的迁移规范问题
你当前的迁移代码直接导入了实际的模型类,不符合Django迁移的设计规范:
- 迁移运行时使用的模型应该是从迁移上下文的
apps对象获取,而非直接import项目里的最新模型,否则后续模型变更后,旧迁移再运行时会出现版本不兼容问题。 - 修正方式:删掉顶部的
from designs.models import Design, ShopifyCollection导入,在转换函数开头通过apps获取对应版本的模型:
def convert_shopify_category_json_objects_to_m2m(apps, schema_editor): Design = apps.get_model('designs', 'Design') ShopifyCollection = apps.get_model('designs', 'ShopifyCollection') # 剩下的原有逻辑不变
额外优化点
add()方法调用后不需要再执行design.save(),多对多关系的修改是直接操作中间表,不会修改Design表本身的字段,多余的save可以删掉。
内容的提问来源于stack exchange,提问作者andreas
相关产品推荐
相关产品推荐

