确保字段对于 Django 模型中的另一个字段是唯一的

Posted

技术标签:

【中文标题】确保字段对于 Django 模型中的另一个字段是唯一的【英文标题】:Ensure field is unique for another field in Django Models 【发布时间】:2021-02-20 10:59:28 【问题描述】:

我希望模型中的一个字段基于另一个字段是唯一的,但反之则不然。

例如:

class Shipment(models.Model):

    supplier = models.ForeignKey("Supplier", on_delete=models.PROTECT, related_name='shipments')
    external_id = models.CharField(max_length=128)

我希望两批货物不能有相同的供应商和相同的external_id,但可以有相同的external_id 和不同的供应商,或者相同的供应商和不同的external_id。

我知道 unique_together。但它使供应商只有一个 external_id。但是,我希望供应商有多个 external_id,而它们都是唯一的。

我可以在 save() 方法中检查这个约束,但我想要一个数据库约束,或者更聪明的东西。

【问题讨论】:

检查一下,你保存在哪里Shipment:if Shipment.objects.filter(supplier_id=supplier_id, external_id=external_id).exists(): raise error here 谢谢,但这就像在 save() 方法中检查它一样。 【参考方案1】:

您是否尝试过使用UniqueConstraint?

class Shipment(models.Model):
    supplier = models.ForeignKey("Supplier", on_delete=models.PROTECT, related_name='shipments')
    external_id = models.CharField(max_length=128)

    class Meta:
        constraints = [models.UniqueConstraint(fields=['supplier', 'external_id'], name='unique_shipment')]


【讨论】:

据我所知,这就像 unique_together 行为。如果我错了,请纠正我。 有点,但根据文档 unique_together 就像会被弃用,所以建议使用 UniqueConstraint 代替。 UniqueConstraint 还具有更多的功能,例如您可以设置一个条件,将 Q 对象作为参数传递。 其实这就是我要找的。带有 Q 对象的约束集。但我不知道怎么做。 无论如何,我不明白 unique_together 或 UniqueConstraint 对您的情况没有帮助,您在使用它们时如何编写代码?你有什么错误信息要查看吗?我也猜 external_id 不应该是空白的 unique_together 和 UniqueConstraint 使供应商只有一个 external_id。但我希望供应商有许多具有不同 external_id 的货物,但它们都是唯一的。不,external_id 可以为空。

以上是关于确保字段对于 Django 模型中的另一个字段是唯一的的主要内容,如果未能解决你的问题,请参考以下文章

Django 1.8:如何确保模型中的两个字段,至少一个或只有一个必须满足条件?

当更新同一模型中的另一个特定字段时,如何更新 Django models.DateTimeField?

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

如何在 Django 中从用户模型的字段自动填充和显示数据到来自不同应用程序的另一个模型?

有条件地只需要 Django 模型表单中的一个字段

django cms 插件上的动态模型选择字段