2015-07-19 3 views
13

Так некоторое время пара миграция после моей первой, я решил, что я хотел, чтобы включить эти поля:Django 1.8 Migrations. Добавление DateTimeField после создания db. Лучшие практики?

created = models.DateTimeField(auto_now_add=True) 
modified = models.DateTimeField(auto_now=True) 

в одну из моих моделей. Когда я makemigrations он дал мне You are trying to add a non-nullable field 'created' to episode without a default; we can't do that (the database needs something to populate existing rows).

Так я тогда изменил его

created = models.DateTimeField(auto_now_add=True, default=datetime.now) 

После снова пытается makemigrations, он сказал, что at_api.Episode.modified: (fields.E160) The options auto_now, auto_now_add, and default are mutually exclusive. Only one of these options may be present.

Хорошо, так что я просто пошел вперед и сняли auto_now_add

created = models.DateTimeField(default=datetime.now) 

Я мог бы сейчас makemigrations без проблем. И затем я позже удалил default=datetime.now и заменил его на auto_now_add=True и без проблем переместился снова. Однако я не могу не чувствовать, что это может быть не лучший способ сделать что-то. Я чувствую, что что-то может пойти не так позже в проекте.

ответ

7

Я думаю, что лучшей практикой здесь было бы сделать поля нулевыми. Что означает ваше поле created: «Время, когда экземпляр был создан, или произвольное время, когда я выполнил миграцию». Стандартный способ представления отсутствия значения - NULL, а не произвольное значение.

При этом, если вы хотите использовать какое-то произвольное значение, вам просто нужно сказать Django, что это такое. Обычно makemigrations дает вам возможность указывать одноразовое значение для существующих строк - не так ли?

Более трудоемким методом было бы объявить поле нулевым, затем создать миграцию данных, чтобы заполнить нужное значение, а затем сделать его недействительным. То, что вы сделали, в основном упрощенная версия. Я не вижу в этом никаких проблем, связанных с продвижением вперед, кроме вопроса created, на самом деле не являющегося временем создания экземпляра.

+0

Да, django спрашивал меня о единовременном значении для существующих строк. Я попробовал 'datetime.now', но он, похоже, не работал. Но я полагаю, что все в целом хорошо? Является ли типичным установить «null = True» в качестве «заполнителя» для существующих значений строк, а затем удалить его позже, чтобы заменить что-то еще? – pyramidface

+0

'datetime.now()' работал бы (обратите внимание на круглые скобки - вы хотите * вызвать * функцию и использовать ее возвращаемое значение). Вы добавляете и удаляете «null = True» в более сложных случаях, когда вы хотите присвоить другое значение различным строкам. Например, предположим, что у вас была фактическая дата создания, хранящаяся в файле где-нибудь. Вы должны написать миграцию данных, которая для каждой строки искала дату в файле, а затем помещала ее в базу данных. После этого вы можете удалить «null = True» и снова выполнить миграцию. –

+0

Ах, ладно, я буду помнить это о будущих проектах. Благодаря!! – pyramidface

1

У меня была точно проблема. Я использую Django 1.10. Я прочитал ответ Кевина, и я попытался установить значение по умолчанию, когда Django попросил меня заполнить его как строку datetime.now. И я был удивлен, потому что, за исключением тех полей, Django автоматически спросит вас, если вы хотите использовать datetime.now по умолчанию:

$ ./manage.py makemigrations 
You are trying to add the field 'date_created' with 'auto_now_add=True' to projectasset without a default; the database needs something to populate existing rows. 

1) Provide a one-off default now (will be set on all existing rows) 
2) Quit, and let me add a default in models.py 
Select an option: 1 
Please enter the default value now, as valid Python 
You can accept the default 'timezone.now' by pressing 'Enter' or you can provide another value. 
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now 
Type 'exit' to exit this prompt 
[default: timezone.now] >>> 

Итак, я просто подтвердить, что и все, кажется, работает нормально!

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