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

Cha*_*ntz 9 django many-to-many foreign-keys django-models django-south

我正在使用South在Django的一个模型中更改ForeignKey到ManyToManyField,但它没有按预期工作.

# Original Schema
class Item(models.Model):
    category = models.ForeignKey(Category, default=default_category)
Run Code Online (Sandbox Code Playgroud)

要改为

# Original Schema
class Item(models.Model):
    category = models.ManyToManyField(Category, default=default_category)
Run Code Online (Sandbox Code Playgroud)

所以在评论出模型中的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: 
Run Code Online (Sandbox Code Playgroud)

我对此感到困惑,因为1.我已经指定了一个默认值"default_category"和2.我没有删除任何字段我只是将其更改为ManyToManyField.我的问题是如何在这种情况下继续前进?有没有其他技巧可以使用South进行此转换?

BTW我使用的是South 0.7和Django 1.1.1

谢谢您的帮助.

Joh*_*ohn 17

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

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

您将需要3次迁移才能干净地执行此操作.首先创建一个具有虚拟manytomany关系的schemamigration来保存您的数据.

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

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

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

  • 通常,最好使属性名称适当地复数化,即外键是"类别",但是多对应应该是"类别".如果您实际更改了属性名称,则会使其变得更加微不足道. (7认同)
  • 谢谢.我找到了这个链接http://djangoandother.blogspot.com/2010/12/django-model-migrations-with-south-how.html,它提供了一个描述示例. (5认同)