我正在使用South在Django的一个模型中更改ForeignKey TO ManyToManyField,但它没有按预期运行。
# Original Schema
class Item(models.Model):
category = models.ForeignKey(Category, default=default_category)
更改为
# Original Schema
class Item(models.Model):
category = models.ManyToManyField(Category, default=default_category)
所以在我做模型中注释掉ForeignKey行后,
python manage.py schemamigration affected_model --auto
? The field 'Item.category' does not have a default specified, yet is NOT NULL.
? Since you are removing this field, you MUST specify a default
? value to use for existing rows. Would you like to:
? 1. Quit now, and add a default to the field in models.py
? 2. Specify a one-off value to use for existing columns now
? 3. Disable the backwards migration by raising an exception.
? Please select a choice:
我对此感到困惑,因为1.我已经指定了默认值“default_category”和2.我没有删除任何字段我只是将其更改为ManyToManyField。我的问题是如何在这种情况下继续前进?有没有其他技巧可以使用South进行此转换?
BTW我使用的是South 0.7和Django 1.1.1
感谢您的帮助。
答案 0 :(得分:17)
事实上你正在删除该字段。外键由数据库中的列表示,在该情况下,该列将命名为category_id。 ManyToMany关系由“通过”表表示。使用django,您可以指定直通表,也可以自动为您生成一个。
这是一次非常重要的迁移,您需要手动编写代码。需要了解模型的基础数据库表示是什么。
您需要3次迁移才能干净利落地完成此任务。首先创建一个带有虚拟多人关系的模式移植来保存数据。
然后创建一个数据迁移,将外键关系复制到你的虚拟多人
最后创建schemamigration以删除foreignkey并重命名dummy manytomany表。
步骤2和3都要求您手动编写迁移。我应该强调这是一种非常重要的移民风格。但是,您完全可以理解这些关系对数据库的意义比平均迁移更为可行。如果您的数据很少或没有数据,那么只需删除表并重新开始迁移即可。