首页 文章

Django South - 创建非空的ForeignKey

提问于
浏览
4

我有一个模特

class Mystery(models.Model):
    first = models.CharField(max_length=256)
    second = models.CharField(max_length=256)
    third = models.CharField(max_length=256)
    player = models.ForeignKey(Player)

我添加了播放器ForeignKey但是当我尝试使用South迁移它时,我似乎无法创建这个whith一个null = False . 我有这样的信息:

字段'Mystery.player'没有指定默认值,但是NOT NULL . 由于您要添加此字段,因此必须指定用于现有行的默认值 . 是否要:1 . 立即退出,并在models.py中的字段中添加默认值2.指定现在用于现有列的一次性值

我用这个命令:

manage.py schemamigration myapp --auto

非常感谢 !

3 回答

  • 11

    另一个选择是在添加ForeignKey之前创建data migration,在其中创建具有特定id的新Player实例 . 请确保以前数据库中不存在该ID .

    1.创建数据迁移文件

    $ ./manage.py datamigration myapp add_player
    Created 00XX_add_player.py
    

    2.编辑文件的前向和后向方法:

    def forwards(self, orm):
        orm['myapp.Player'].objects.create(name=u'Very misterious player', id=34)
    
    def backwards(self, orm):
        # Haven't tested this one yet
        orm['myapp.Player'].objects.filter(id=34).delete()
    

    3.将ForeignKey添加到您的Mistery类并再次迁移架构 . 它会询问您的数据迁移ID的默认值,在本例中为34 .

    $ ./manage.py schemamigration --auto myapp
     ? The field 'Mistery.player' does not have a default specified, yet is NOT NULL.
     ? Since you are adding 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
     ? Please select a choice: 2
     ? Please enter Python code for your one-off default value.
     ? The datetime module is available, so you can do e.g. datetime.date.today()
     >>> 34
     + Added field player on myapp.Mistery
    Created 0010_auto__add_field_mistery_player.py. You can now apply this migration with: ./manage.py migrate myapp
    

    4.最后运行migrate命令,它将按顺序执行迁移,插入新的Player并使用对新Player的引用更新所有Mistery行 .

  • 5

    这最好在3次迁移中完成 .

    步骤1.创建新模型并允许玩家为空: player = models.ForeignKey(Player, null=True)

    第2步 . 运行 ./manage.py schemamigration <app> --auto

    第3步 . 运行 ./manage.py datamigration <app> set_default_players

    步骤4.在 <app>/migrations/<number>_set_default_players.py 中向前和向后更新以使用您喜欢的任何逻辑来设置默认播放器 . 确保每个 Mystery 对象都具有 player 的值 .

    步骤5.更新 Mystery 模型,使 player 具有 null=False .

    步骤6.运行 ./manage.py schemamigration <app> --auto

    步骤7.运行 ./manage.py migrate <app>

  • 2

    如果你的数据库已经包含Mystery对象,那么南必须知道, player 字段中放入了什么值,因为它不能为空 .

    一种可能的方案:

    选择

    2. Specify a one-off value to use for existing columns now
    

    然后输入1.因此,所有现有的Mystery对象现在将指向具有pk = 1的播放器 . 然后您可以在管理页面中更改(如果需要) .

相关问题