2013-04-25 5 views
4

У меня есть модельДжанго Юг - создать не Null ForeignKey

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, кажется, что я не могу создать это ти нуль = False. У меня есть такое сообщение:

Поле «Mystery.player» не имеет значения по умолчанию, указанный, но это NOT NULL. Поскольку вы добавляете это поле, вы ДОЛЖНЫ указать значение по умолчанию для использования для существующих строк. Вы хотите:
1. Закройте сейчас, и добавить по умолчанию в поле в models.py
2. Указать одноразовое значение для использования существующих колонн в настоящее время

Я использую эту команду:

manage.py schemamigration MyApp --auto

Спасибо большое!

+2

Если база данных уже содержит мистерия объекты, затем на юг должен знать, какое значение помещается в 'player' поле, потому что он не может быть пустым. Одно из возможных решений: выберите 2. Укажите одноразовый ... и затем введите 1. Таким образом, все ваши существующие объекты Mystery теперь укажут на Player с pk = 1. Затем вы можете изменить (если необходимо) это в admin. – stalk

+0

Большое спасибо за вашу помощь! – MaT

+0

Я напишу это как ответ – stalk

ответ

5

Еще один вариант - создать data migration перед добавлением ForeignKey, в котором вы создаете новый экземпляр Player с определенным идентификатором. Убедитесь, что этот идентификатор не существует ранее в вашей базе данных.

1.Create миграция данных файла

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

2.Edit вперед и назад методы файла:

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.Add ForeignKey к классу Mistery и снова перенастроить схему. Он будет просить значение по умолчанию для вашей миграции данных идентификатора, в данном примере 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.Finally запустить команду перенастройки, и он будет выполнять миграцию в последовательном порядке, вставляя новый плеер и обновление всех строки Mistery со ссылкой на ваш новый Player.

+4

Пожалуйста, не делайте этого. Это решение может легко укусить вас в будущем, когда кто-то еще выполнит миграцию. Что, если у них уже есть объект с идентификатором, например? В общем, выбор произвольного идентификатора и перенос его в миграцию, вероятно, следует считать очень плохой практикой. См. Мое предложенное решение. – Josh

2

Если ваша база данных уже содержит объекты Mystery, то юг должен знать, какое значение положить в поле player, потому что оно не может быть пустым.

Одно из возможных решений:

выбрать

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

, а затем введите 1. Таким образом, все существующие Mystery объектов теперь указывают на плеер с рк = 1. Тогда можно изменить (если это необходимо) это на странице администратора.

11

Это лучше всего сделано в 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>

+0

Этот ответ кажется лучше, чем принятый. Единственное изменение, которое я предлагаю, это то, что «null = True» должно быть «blank = True», если целью является разрешить null. (интуитивный №) –

+0

Не могли бы вы объяснить немного больше, почему вы так думаете? 'blank' влияет только на валидацию и поэтому не должен применяться в течение краткого периода, когда поле является нулевым. См. Https://docs.djangoproject.com/en/1.8/ref/models/fields/#blank – Josh

+0

. Мой плохой. Поймал еще раз жестоко разбитую документацию по джанго. 'null = True' правильный. –

Смежные вопросы