【问题标题】:How do you specify a default for the Django ForeignKey field?如何为 Django ForeignKey 字段指定默认值?
【发布时间】:2011-08-16 15:09:11
【问题描述】:

我正在尝试使用 South 将 ForeignKey 字段添加到 Django 模型。我收到以下错误:

ValueError: You cannot add a null=False column without a default value.

事实上,我确实为该字段指定了一个默认值,但我不确定我是否正确。

language = models.ForeignKey(Language, default=Language.objects.all()[0])

这应该有效吗?

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    AFAIK Django 不会执行作为参数传递的 QuerySet,即使它仅限于一个元素。您应该尝试类似建议的in this post

    class Foo(models.Model):
        a = models.CharField(max_length=10)
    
    def get_foo():
        return Foo.objects.get_or_create(id=1)
    
    class Bar(models.Model):
        b = models.CharField(max_length=10)
        a = models.ForeignKey(Foo, default=get_foo)
    

    【讨论】:

    • 我会发布相同的。另外,如果 Foo 没有数据,您可以在 get_foo 中创建一个默认元素。
    • 是的,使用 get_or_create 是个好主意!
    • 这并不真正起作用,假设唯一的一点是通过 id 以外的东西进行查询。这是因为查询是在创建迁移之前运行的,并且生成的 id 被硬编码到迁移中。因此,如果稍后运行迁移的任何人对所需记录有不同的id,他们仍将获得您的id,而不是在他们的数据库上运行查询,因此将获得随机默认值。
    【解决方案2】:

    因为get_or_create返回一个元组,我认为这是一个更好的解决方案

    def get_default():
        result, _ = Foo.objects.get_or_create(id=1)
        return result
    

    比这个

    return Foo.objects.get_or_create(id=1)
    

    【讨论】:

      【解决方案3】:

      这确实是@radious 答案的扩展。如果你想删减代码行,你也可以默认使用 lambda

      class Foo(models.Model):
          a = models.CharField(max_length=10)
      
      class Bar(models.Model):
          b = models.CharField(max_length=10)
          a = models.ForeignKey(Foo, default=lambda: Foo.objects.get_or_create(id=1)[0])
      

      请注意,您必须在 get_or_create() 上使用索引 0,因为该方法返回一个元组,因此您需要获取对象,而不是元组。

      https://docs.djangoproject.com/en/1.6/ref/models/querysets/#get-or-create

      【讨论】:

      • Django 无法序列化 lambda 表达式
      • @HasanIqbal 评论的相关性是这意味着这种方法在 Django 1.7 之后将不起作用(假设您正在使用迁移)-docs
      猜你喜欢
      • 2010-10-30
      • 2015-09-10
      • 1970-01-01
      • 2011-05-25
      • 1970-01-01
      • 2015-05-18
      • 2022-11-12
      • 1970-01-01
      • 2013-12-29
      相关资源
      最近更新 更多