Django 如何使 ForeignKey 使用默认值?

Posted

技术标签:

【中文标题】Django 如何使 ForeignKey 使用默认值?【英文标题】:Django How to make a ForeignKey use a default? 【发布时间】:2011-02-27 07:09:24 【问题描述】:

我在将 ForeignKey 默认为零时遇到问题,它一直告诉我该字段是必需的,或者如果我尝试不同的迭代,它会抱怨该字段不能为空。

我不确定我做错了什么,但如果 ForeignKey 为 null,我需要将其默认为零。

我正在尝试一个想法来持有几个不同实体(即:公司和员工、公司和赞助商等、公司和供应商等)之间的所有合同。

这些关系都在起作用,但是我的 ForeignKey 语句不允许我使用默认值 0(零)。

# relationships
# Only the company field should be required, the others are optional
# This is so you can link a company with either a sponsor OR a worker
#
sponsor     = models.ForeignKey('Sponsor', null=True, default=0, blank=False)
company     = models.ForeignKey('Company')
worker      = models.ForeignKey('Worker', null=False, default=0, blank=False)

# possible future relationships (not implemented)
#suppliers       = models.ForeignKey('Supplier', null=True, default=0, blank=False)

理想情况下,我希望只有公司字段是必需的,其他都是可选的,默认为零。

这个想法是有一个表来规则/管理不同实体之间的所有合同。

伪代码

合同; id = 1 |公司 ID = 1 |赞助商 ID = 0 | worker_id = 1 |长度 = 10 |工资 = 10000

// 等等

我已经尝试了以下迭代。

# models.ForeignKey('Sponsor', null=False, default=0, blank=True) # This makes the field required

# models.ForeignKey('Sponsor', null=True, default=0, blank=True) # This complains that "Contracts.sponsor" does not allow null values. 

任何关于如何使 ForeignKey 使用默认值的指针将不胜感激。

非常感谢。

编辑。添加导致错误的代码;这是代码的精简版。

// company.py
class Company(models.Model):
    """(Company description)"""

    sponsorContracts = models.ManyToManyField('Sponsor', through='Contracts', db_column='sponsor_id')
    employees   = models.ManyToManyField('Worker', through='Contracts', db_column='worker_id')

// contracts.py
class Contracts(models.Model):
    """(Contracts description)"""
        # relationships
    sponsor             = models.ForeignKey('Sponsor', null=True, default=0, blank=True)
    company             = models.ForeignKey('Company')
    worker              = models.ForeignKey('Worker', null=False, default=0, blank=False)

// worker.py
class Worker(models.Model):
    """(A list of employees)"""

    employer            = models.ManyToManyField('Company', through='Contracts', db_column='company_id')


// sponsor.py
class Sponsor(models.Model):
    """(A list of sponsors)"""

    sponsorContracts    = models.ManyToManyField('Company', through='SponsorContracts')

【问题讨论】:

您收到的错误是什么,产生它的确切代码是什么? "ValueError at /admin/myapp/contracts/add/ 无法分配无:"Contracts.sponsor" 不允许空值",另一个是:"IntegrityError at /admin/myapp/contracts /add/ myapp_contracts.sponsor_id 不能为 NULL" 添加了代码以在原始问题中为问题提供上下文。 【参考方案1】:

实体之间的关系要么存在(对另一个表中的 id 的有效引用),要么不存在(值 undefined - null)。如果您确实“需要”一个不引用有效实体的非空值,您可以尝试在引用的表中定义一个“默认”实体,并为其定义默认值。

但在大多数情况下,我会质疑要求非空默认 FK 值的有效性。虽然我在一两种情况下做过类似的事情:

User(id, username, gender_id)
Gender(id, value)

Gender:
id 1 value unknown
id 2 value male
id 3 value female

实际上,null 被称为未定义的值,在大多数情况下都应该这样使用。

【讨论】:

您的意思是在您用作默认实体的各个实体中添加一行(例如第 1 行 = 未知)?我认为这是有道理的。 @zardon 是的,这就是我的意思。但前提是您绝对必须这样做,并且不能使用 null 来表示“未知”。【参考方案2】:

ForeignKey 如何默认为 0? FK 的全部意义在于它受限于另一个表中的键值。该表中不能有 ID 为 0 的行,因此 0 不是 FK 的有效值。

如果您希望模型实例与其他几个表之一建立关系,您可能需要Generic relations。

【讨论】:

这只是我在玩的一个实验性想法。我有多个实体,每个实体都与一个公司实体签订“合同”,但我认为让 1 个实体控制合同而不是让 6 个几乎做同样事情的实体更容易。我来看看通用关系

以上是关于Django 如何使 ForeignKey 使用默认值?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用'select_related'从相关(ForeignKey)django模型中接收并非所有字段

如何使唯一 = true 的外键在 Django 中成为“可选”?

Django:如何从 ManyToMany 迁移到 ForeignKey?

Django:如何获取列表相关的 ForeignKey 记录?

Django:如何使用 ModelFormSet 和 FormWizard 过滤 ForeignKey 选择(例如使用 request.user)?

Django:如何向后跟随 ForeignKey('self')