使用South将ForeignKey转换为ManyToManyField无法正常工作

时间:2011-06-28 16:19:58

标签: django django-models foreign-keys many-to-many django-south

我正在使用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

感谢您的帮助。

1 个答案:

答案 0 :(得分:17)

事实上你正在删除该字段。外键由数据库中的列表示,在该情况下,该列将命名为category_id。 ManyToMany关系由“通过”表表示。使用django,您可以指定直通表,也可以自动为您生成一个。

这是一次非常重要的迁移,您需要手动编写代码。需要了解模型的基础数据库表示是什么。

您需要3次迁移才能干净利落地完成此任务。首先创建一个带有虚拟多人关系的模式移植来保存数据。

然后创建一个数据迁移,将外键关系复制到你的虚拟多人

最后创建schemamigration以删除foreignkey并重命名dummy manytomany表。

步骤2和3都要求您手动编写迁移。我应该强调这是一种非常重要的移民风格。但是,您完全可以理解这些关系对数据库的意义比平均迁移更为可行。如果您的数据很少或没有数据,那么只需删除表并重新开始迁移即可。