【问题标题】:'NOT NULL constraint failed' after adding to models.py添加到 models.py 后,“NOT NULL 约束失败”
【发布时间】:2014-11-15 20:13:19
【问题描述】:

我正在使用 userena 并在我的 models.py 中添加以下行

zipcode = models.IntegerField(_('zipcode'),
                                   max_length=5)

点击注册表单上的提交按钮后出现以下错误:

IntegrityError at /accounts/signup/
NOT NULL constraint failed: accounts_myprofile.zipcode

我的问题是这个错误是什么意思,这与 Userena 有关系吗?

【问题讨论】:

  • 您运行迁移了吗?默认情况下,Django 不会接受对模型的更改。而且,如果不指定null=True, blank=True,则成为必填字段
  • 设置 null 和空白不会改变任何东西。即使删除属性也无济于事。

标签: django django-models


【解决方案1】:

您必须创建一个迁移,在其中为新字段指定默认值,因为您不希望它为空。如果不需要 null,只需添加 null=True 并创建并运行迁移。

【讨论】:

  • 注意:您可能必须先删除已经存在的迁移文件才能再次运行 makemigrations 和迁移。
  • 此错误发生一次后,迁移不会运行。
  • @lolesque 你的解决方案对我有用,我还需要删除 db.sqlite3,谢谢!
【解决方案2】:

coldmindanswer 是正确的,但缺少细节。

NOT NULL constraint failed 在未明确允许的情况下尝试将 None 设置为 zipcode 属性时发生。

这通常发生在:

  1. 你的字段默认有Null=False,所以当对象被创建并保存在数据库中时,数据库中的值不能是None(即未定义)(这发生在objects_set.create()调用或设置.zipcode 属性并进行 .save() 调用)。

    例如,如果您的代码中某处的赋值导致:

    model.zipcode = None
    

    引发此错误。

  2. 在创建或更新数据库时,Django 会约束找到一个默认值来填充该字段,因为默认情况下是Null=False。它找不到任何内容,因为您尚未定义任何内容。那么这个错误不仅可能发生在代码执行过程中,还可能发生在创建数据库的时候呢?

  3. 请注意,如果您定义default=None,或者如果您的默认值类型不正确,例如default='00000'而不是00000,则会返回相同的错误(也许可以在char 和 integers,但我建议不要依赖它。此外,显式优于隐式)。如果默认值违反 max_length 属性,则很可能还会引发错误,例如123456

    因此,您必须通过以下方式之一定义该字段:

    models.IntegerField(_('zipcode'), max_length=5, Null=True,
       blank=True)
    
    models.IntegerField(_('zipcode'), max_length=5, Null=False,
       blank=True, default=00000)
    
    models.IntegerField(_('zipcode'), max_length=5, blank=True,
       default=00000)
    

    然后进行迁移 (python3 manage.py makemigration <app_name>),然后迁移 (python3 manage.py migrate)。

    为了安全你也可以删除<app_name>/migrations/中最后一个失败的迁移文件,通常以这种模式命名:

    <NUMBER>_auto_<DATE>_<HOUR>.py
    

最后,如果您不设置Null=True,请确保mode.zipcode = None 永远不会在任何地方设置。

【讨论】:

  • 要求将其保留为必填字段。这里也是一个整数字段,我正在制作一个外键并抛出相同的错误。欲了解更多信息,我的Question
  • 我正面临这个问题,但是如果我使用null=True 它在数据库中保存为空,它应该保存用户ID,当我删除null=True 时,它会显示此错误,没看懂问题,我按照django rest framework中的教程来的
【解决方案3】:

如果 zipcode 字段不是必填字段,则添加 null=True 和 blank=True,然后运行 ​​makemigrations 和 migrate 命令以成功反映数据库中的更改。

【讨论】:

    【解决方案4】:

    在 models.py 中,您应该将null=True 添加到邮政编码字段。

    【讨论】:

      【解决方案5】:

      由于您向模型添加了新属性,因此您必须先删除数据库。然后是 manage.py 迁移,然后是 manage.py 迁移。

      【讨论】:

      • 对于任何遇到此答案的人。请注意,更新模型时不需要删除数据库,这将是一个巨大的痛苦,并且不太可能解决这里讨论的问题。
      猜你喜欢
      • 2015-04-22
      • 2018-08-24
      • 2022-01-19
      • 2021-11-16
      • 2020-12-18
      • 2021-03-20
      • 2020-02-11
      • 2019-02-13
      • 2017-12-31
      相关资源
      最近更新 更多