由属性确定的唯一数据库条目

Posted

技术标签:

【中文标题】由属性确定的唯一数据库条目【英文标题】:Unique database entry determined by attributes 【发布时间】:2019-12-24 10:52:24 【问题描述】:

我有以下课程:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=200)
    age = models.CharField(max_length=200)

我创建了这个类的两个相同的实例:

alex_1 = Person(name='Alex', age=30)
alex_1.save()
alex_2 = Person(name='Alex', age=30)
alex_2.save()

这将在人员数据库中保存 2 个条目。有什么方法可以防止第二个实例 (alex_2) 被保存,因为它在技术上是重复的?即,您可以为models.Model 实例实现__eq____hash__ 函数吗?

【问题讨论】:

【参考方案1】:

截至django-2.2,您可以在字段的组合上使用UniqueConstraint [Django-doc]:

from django.db.models.constraints import UniqueConstraint

class Person(models.Model):
    name = models.CharField(max_length=200)
    age = models.CharField(max_length=200)

    class Meta:
        constraints = [
            UniqueConstraint(fields=['name', 'age'], name='person_unique')
        ]

这意味着nameage 值的组合 应该是唯一的。所以Person(name='Alex', age=30)Person(name='Alex', age=40)不会报错,但是Person(name='Alex', age=30)Person(name='Alex', age=30)这两个对象会报错,比如:

django.db.utils.IntegrityError: (1062, "Duplicate entry 'Alex-30' for key 'person_unique'")

django-2.2之前可以使用unique_together [Django-doc]:

class Person(models.Model):
    name = models.CharField(max_length=200)
    age = models.CharField(max_length=200)

    class Meta:
        unique_together = ['name', 'age']

【讨论】:

太好了,谢谢。这会阻止第二个实例被保存吗? @alex_lewis: 是的,通常它会为第二次插入引发IntegrityError,通常在数据库级别强制执行。 酷,您在我发表评论时澄清了这一点。我很快就会接受....再次感谢 @alex_lewis:是的,这是正确的,将它包含在代码示例中可能确实更好,谢谢:)。 好答案,赞成。我认为 unique_together 应该是unique_together = (['name', 'age'],)

以上是关于由属性确定的唯一数据库条目的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 XML::XPath 获取属性?

数据库01-范式总结

Vue.js 只显示具有唯一属性的对象

清理数据库条目

使用用户信息条目记录核心数据实体属性

无法添加类型为“add”且唯一键属性“name”设置为“aspNetCore”的重复集合条目