【问题标题】:ForeignKey does not allow null valuesForeignKey 不允许空值
【发布时间】:2013-05-11 10:37:40
【问题描述】:

我正在使用 Django REST Framework 2.0。

这是我的模型类:

class Mission(models.Model):
  assigned_to = models.ForeignKey('auth.User',
                                   related_name='missions_assigned',
                                   blank = True)

这是我的视图类:

class MissionList(generics.ListCreateAPIView):
    model = Mission
    serialize_class = MissionSerializer
  1. 多部分表单在浏览器中呈现,assigned_to 字段的选择为空。

  2. 发布原始 JSON 时,我收到以下错误消息:

Cannot assign None: "Mission.assigned_to" does not allow null values.

【问题讨论】:

    标签: django-rest-framework model foreign-keys serialization


    【解决方案1】:

    blank 选项用于表单验证,null 用于写入数据库。

    因此您可以将null=True 添加到该字段。

    编辑:继续评论

    考虑保存对象时的两个步骤:

    1. 验证器(由blank控制)
    2. 数据库限制(由null控制)

    对于default选项,以IntegerField为例,
    default=5, blank=True, null=False,即使你没有赋值(有blank=True),也通过(1),通过(2),因为它有默认值 (5) 并将 5 而不是 None 写入 DB。
    blank=True, null=False,通过 (1) 而不是 (2),因为它尝试将 None 写入 DB。

    因此,如果您想将字段设为可选,请使用default=SOMETHING, blank=True, null=Falseblank=True, null=True

    另一个例外是类似字符串的字段,例如CharField
    建议使用blank=True单独,留下null=False
    这使得字段要么是字符串(>=1 char(s)),要么是空字符串('',len()==0),而不是None

    原因是当null=True被设置时,状态“未设置”会有两个可能的值:空字符串和None,这很容易混淆(并且可能导致错误)。

    【讨论】:

    • 这意味着blank = True 必须始终与null = True 一起使用?为什么我不能在我的表格中选择空?我确实使用了blank = True
    • assigned_to==None 通过了表单验证器,但没有通过数据库。如果没有null=True,您将无法将None 写入数据库。因此,通常,如果您想要一个可选字段,请将blanknull 都设置为True
    • 但是,有两个例外,default 选项和类似字符串的字段。 (我想在帖子之后而不是在这里添加评论。)
    • 我想指出null 也会影响数据库限制背后的行为(请参阅code.djangoproject.com/ticket/12708
    • link 将对blank and null 有所帮助
    【解决方案2】:

    如果设置了此行为,ForeignKey 允许空值。 您的代码将如下所示:

    class Mission(models.Model):
        assigned_to = models.ForeignKey(
            'auth.User',
            related_name='missions_assigned',
            blank=True,
            null=True
        )
    

    你必须写 null=True

    注意:更改模型后,需要运行python manage.py makemigrations yourappname,然后运行python manage.py migrate

    【讨论】:

    • 更新现有模型时会报错。有一些方法可以通过它,最简单的是删除现有数据库。请参阅此处的示例解决方案:coderbook.com/@marcus/…
    • @JakubJabłoński 你能详细说明为什么会导致错误吗?使ForeignKey 可以为空并进行迁移是一种常见操作,不应给出任何错误。我一直这样做。
    • @JakubJabłoński 您可能会考虑相反的情况,将模型从“允许为空”移动到“必须有值”,在这种情况下添加手动迁移以提供默认值或正如您所建议的,从头开始将是一个解决方案。不过,上面讨论的解决方案没有问题。
    【解决方案3】:

    更改模型并允许 null 的解决方案:

    blank=True,
    null=True
    

    对我来说还不够。

    我可以通过将序列化程序中的 required 设置为 false 来解决问题,例如

    field = MyModelSerializer(required=False)
    

    here (Django ForeignKey field required despite blank=True and null=True) 所述。

    我最终都做了。允许模型中带有 blank=True, null=True 的 null 并且不需要 required=False 序列化程序中的字段

    【讨论】:

      【解决方案4】:

      就我而言,required=False 还不够。我在序列化程序中需要allow_nullper Django ForeignKey field required despite blank=True and null=True

      【讨论】:

        猜你喜欢
        • 2011-07-14
        • 1970-01-01
        • 2015-06-29
        • 2013-12-29
        • 1970-01-01
        • 2018-04-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多