我有一个模型
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,但当我尝试使用南方迁移它时,似乎我不能用null=False创建这个。我有这样的消息:
字段"Mystery"。Player '没有指定默认值,但是有非空。既然你要添加这个字段,你必须指定一个默认值值用于现有行。你想:
1. 现在退出,并在models.py
中添加一个默认值。2. 为现有列指定一次性值
我使用这个命令:
manage.py schemmigrate myapp——auto
最好在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>
另一个选择是在添加ForeignKey之前创建一个数据迁移,在这个迁移中,您可以创建一个具有特定id的新Player实例。请确保该id以前在数据库中不存在。
1。创建数据迁移文件
$ ./manage.py datamigration myapp add_player
Created 00XX_add_player.py
2。编辑文件的forward 和backward 方法:
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行。
如果您的数据库中已经包含了Mystery对象,那么您必须知道在player
字段中放入了什么值,因为它不能为空。
一个可能的解决方案:
选择 2. Specify a one-off value to use for existing columns now
,然后输入1。所以你现有的所有神秘物体现在将指向玩家pk = 1。然后你可以在管理页面修改(如果需要)。