Django 1.8迁移。在数据库创建后添加DateTimeField。最佳实践?

Django 1.8迁移。在数据库创建后添加DateTimeField。最佳实践?,django,datetime,django-models,django-migrations,Django,Datetime,Django Models,Django Migrations,因此,在第一次迁移之后的一段时间,我决定要包括以下字段: created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) 我的一个模特。当我makemigrations它给了我 您试图在没有默认设置的情况下将不可为空的字段“created”添加到插曲中;我们不能那样做(数据库需要 用于填充现有行的内容)。 于是我把它改成了 created = models.Date

因此,在第一次迁移之后的一段时间,我决定要包括以下字段:

created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
我的一个模特。当我
makemigrations
它给了我
您试图在没有默认设置的情况下将不可为空的字段“created”添加到插曲中;我们不能那样做(数据库需要
用于填充现有行的内容)。

于是我把它改成了

created = models.DateTimeField(auto_now_add=True, default=datetime.now)
在再次尝试
makemigrations
之后,它说
at_api.eption.modified:(fields.E160)选项auto_now、auto_now_add和default是互斥的。只有一个
可能存在这些选项中的一个。

好吧,我只是继续,删除了自动添加

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

我现在可以
makemigrations
,没有任何问题。后来我删除了
default=datetime.now
,并将其替换为
auto\u now\u add=True
,然后重新迁移,没有任何问题。然而,我忍不住觉得这可能不是最好的做事方式。我觉得项目的后期可能会出现问题。

我认为最好的做法是将字段设置为空。此时,您的
created
字段的意思是:“创建实例的时间,或我运行迁移的任意时间。”表示缺少值的标准方式是
NULL
,而不是任意值

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


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

我刚刚遇到了确切的问题。我使用Django 1.10。我读了Kevin的答案,当Django要求我将其填入
datetime.now
string时,我试着输入默认值。 我很惊讶,因为对于这些字段,Django会自动询问您是否要使用
datetime。现在,
作为默认值:

$ ./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] >>>

所以,我只是确认一下,一切似乎都很好

是的,django确实问过我关于现有行的一次性值。我尝试了datetime。现在,但似乎不起作用。但我想一切都好吧?将
null=True
设置为现有行值的“占位符”,然后稍后将其删除以替换为其他值是典型的做法吗?
datetime.now()
会起作用(注意括号-您希望调用函数并使用其返回值)。在需要为不同行分配不同值的更复杂的情况下,可以添加和删除
null=True
。例如,假设您将实际创建日期存储在某个文件中。您可以编写一个数据迁移,对于每一行,查找文件中的日期,然后将其放入数据库。在那之后,您可以删除
null=True
并再次迁移。谢谢它可能在时区下工作。现在至少在Django的更高版本上工作