Django 1.8迁移.在数据库创建后添加DateTimeField.最佳做法?

pyr*_*ace 14 django datetime django-models django-migrations

所以有一次在我的第一次迁移之后进行了几次迁移,我决定将这些字段包括在内:

created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
Run Code Online (Sandbox Code Playgroud)

进入我的一个模特.我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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

我现在可以makemigrations没有任何问题.然后我删除default=datetime.now并替换它auto_now_add=True,并再次迁移没有任何问题.但是,我不禁觉得这可能不是最好的做事方式.我觉得项目后期可能出现问题.

Kev*_*nry 9

我认为这里最好的做法是让这些字段可以为空.您的created字段目前意味着:"创建实例的时间,或者我运行迁移的任意时间." 表示缺少值的标准方法是NULL,而不是任意值.

也就是说,如果你想使用一些任意值,你只需要告诉Django它是什么.通常makemigrations为您提供指示用于现有行的一次性值的选项 - 这是不是会发生?

一个更费力的方法是将字段声明为可空,然后创建数据迁移以填充所需的值,然后使其不可为空.你所做的基本上是简化版.除了created实际上不是创建实例的问题之外,我不认为它会产生任何问题.


Dar*_*wic 5

我刚刚遇到了确切的问题。我使用 Django 1.10。我阅读了 Kevin 的回答,当 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] >>>
Run Code Online (Sandbox Code Playgroud)

所以,我只是确认一下,一切似乎都正常!