我是Django的新手。
IntegrityError: (1364, "Field 'created_at' doesn't have a default value")
在我没有为在model.py中定义的模型编写created_at
时发生。
每次遇到这样的错误,我都会添加
created_at = models.DateTimeField(default=timezone.now, null=True)
到models.py,然后运行python manage.py makemigrations; python manage.py migrate --fake
。
可以吗? (我的意思是,它是否遵循Django最佳实践?)
当我使用Rails时,我从未遇到过这样的问题。为什么Django不会自动处理created_at
列?
此外,我想知道为什么--fake
选项会删除此错误。
Django==1.11.5
mysqlclient==1.3.12
Python 3.6.1
提前致谢。
答案 0 :(得分:4)
似乎您希望在每次创建模型实例时设置属性created_at
。有一种更简单的方法:
created_at = models.DateTimeField(auto_now_add=True)
这里的文档详细解释了https://docs.djangoproject.com/en/1.11/ref/models/fields/#django.db.models.DateField.auto_now_add
答案 1 :(得分:1)
根据您的评论,我想我可以重现您的步骤。您在models.py
中有一个模型类:
from django.db import models
class YourModel(models.Model):
one_field = models.CharField()
another_field = models.CharField()
然后你跑了:
python manage.py makemigrations
python manage.py migrate
之后,您添加到模型类中:
from django.db import models
class YourModel(models.Model):
one_field = models.CharField()
another_field = models.CharField()
created_at = models.DateTimeField(default=timezone.now, null=True)
但忘记运行迁移并收到错误消息。
这是因为Django ORM正在寻找在数据库中找不到的属性created_at
。
您必须运行命令:
python manage.py makemigrations
python manage.py migrate
一次。请记住,选项--fake
不会更改数据库。它只是将迁移标记为运行。只有在你确定自己在做什么时才使用它。
正如Johannes reichard建议你为此目的更好地使用auto_now_add
(并且还有auto_now
)。查看official documentation。
缺点是此字段不会显示在管理员中。解决方法是覆盖保存方法:
def save(self, *args, **kwargs):
if not self.pk:
self.created_at = timezone.now() # import it from django.utils
super(YourModel, self).save(*args, **kwargs)