【问题标题】:Django MySQL IntegrityError: ("Field 'created_at' doesn't have a default value")Django MySQL IntegrityError:(“字段'created_at'没有默认值”)
【发布时间】:2017-09-26 13:21:14
【问题描述】:

我是 Django 新手。

IntegrityError: (1364, "Field 'created_at' doesn't have a default value") 

当我没有为我在 models.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

提前致谢。

【问题讨论】:

  • 最佳做法是在每次更改 models.py 后运行 python manage.py makemigrations app_labelpython manage.py migrate app_label。选项 --fake 将迁移标记为已完成,而无需实际执行 SQL 代码来更改数据库架构。
  • @cezar 谢谢,你对--fake 的解释很容易理解。如果我在每次更改后运行迁移命令,"Field 'created_at' doesn't have a default value" 不会发生?
  • 从这里很难说这个问题是如何潜入你的代码的。您是否创建了一个模型类,然后将字段 created_at 添加到其中?
  • @cezar 是的,因为习惯了Rails风格,第一次忘记定义created_at列,迁移后添加了这个clumn。

标签: python mysql django


【解决方案1】:

您似乎希望在每次创建模型实例时设置一个属性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

【讨论】:

    【解决方案2】:

    从你的 cmets 我想我可以重现你的步骤。你的 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)
    

    【讨论】:

      猜你喜欢
      • 2016-12-27
      • 2013-04-18
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      • 1970-01-01
      • 2013-03-04
      • 1970-01-01
      相关资源
      最近更新 更多