两个外键字段,正好一个被设置为一个值,另一个在 MySQL 数据库的 django 模型中为空

Posted

技术标签:

【中文标题】两个外键字段,正好一个被设置为一个值,另一个在 MySQL 数据库的 django 模型中为空【英文标题】:Two foreign key fields, exactly one is set to a value, the other null in django model with MySQL database 【发布时间】:2013-12-27 18:24:57 【问题描述】:

我有一个带有两个外键字段的 django 模型,一个指向产品,另一个指向下面代码中的投资组合。应该为每个 Lca 记录设置其中一个。我知道我可以用 mysql 触发器做到这一点,但我想知道是否有办法在 django 中进行这种条件保存

class Lca(models.Model):
    product             = models.ForeignKey(product, null=True, blank=True)
    portfolio           = models.ForeignKey(portfolio, null=True, blank=True)
    carbon_price        = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    name                = models.CharField(max_length=255, blank=True)
    total_footprint     = models.IntegerField(blank=True, null=True)
    calculation_type    = models.CharField(max_length=9)
    total_cv            = models.DecimalField(max_digits=10, decimal_places=0, blank=True, null=True)
    source              = models.CharField(max_length=255, blank=True)
    date_from           = models.DateField()
    date_to             = models.DateField(blank=True, null=True)

    def __unicode__(self):
        return self.name
    # end __unicode__
# end

【问题讨论】:

【参考方案1】:

你可以override模型的save方法:

def save(self, *args, **kwargs):
    if self.product and self.portfolio or not self.product and not self.portfolio:
        raise ValueError('Exactly one of [Lca.product, Lca.portfolio] must be set')

    super(Lca, self).save(*args, **kwargs)

注意此方法不适用于bulk_create

【讨论】:

【参考方案2】:

如果您从表单请求数据,您可以使用clean forms validations。

【讨论】:

【参考方案3】:

我建议为您要添加的任何自定义验证添加一个模型 clean() 方法。模型清理方法由 ModelForms 自动调用,但不是由 save() 自动调用,因此您可能需要自己调用模型 full_clean() 方法并在发生时处理 ValidationErrors,具体取决于您的用例。

有关Model.clean() 的更多信息,请参阅Django documentation。

【讨论】:

以上是关于两个外键字段,正好一个被设置为一个值,另一个在 MySQL 数据库的 django 模型中为空的主要内容,如果未能解决你的问题,请参考以下文章

django关系类型字段

Django 关系类型字段

mysql 设置外键,能否将表中多个字段关联到另一个表中的同一字段

mysql外键

MySQL数据库8(十九)外键

如何根据具有外键关系的另一个模型更新 Django 模型的字段