如何执行条件唯一性约束 [英] how to enforce a conditional uniqueness constraint
问题描述
说我有一堆表,其中对象被标记为已删除,而不是实际删除.现在,我要强制执行一个约束,即只有一个具有特定字段值的未删除对象,但是我可以有多个具有相同字段值的已删除对象.
class Deletable(models.Model):已删除= models.BooleanField(default = False)类Meta:abstract =真实def soft_delete():self.deleted =真实self.save()class ConcreteModel(Deletable):一个= models.IntegerField()b = models.IntegerField()类Meta:#wrong,因为可能有一些已删除的行unique_together =('a','b')
实施约束的最佳方法是什么?
在另外一个字段( deleted
)和伪唯一字段中定义唯一约束.然后,代表软删除,将模型的ID分配给 deleted
;对于未删除的项目,请分配0.
使用这种方法,对于未删除的项目,由于 deleted
字段的值是一致的,因此多字段唯一约束将有效地忽略 deleted
的值并强制执行仅伪唯一字段的唯一性;对于已删除项目,将考虑 deleted
,并且由于它是唯一的,因此该约束始终可以满足-因此,可以使用具有相同伪唯一字段值的任何数量的模型共存.>
例如,以下代码可能就是您想要的.
class Deletable(models.Model):已删除= models.IntegerField(默认= 0)类Meta:abstract =真实def soft_delete():self.deleted = self.idself.save()class ConcreteModel(Deletable):一个= models.IntegerField()b = models.IntegerField()类Meta:unique_together =('a','b','已删除')
Say I have a bunch of tables where the objects are marked deleted rather than actually deleted. Now, I want to enforce a constraint that there can be only one non-deleted object with a particular set of field values, but I can have multiple deleted objects with the same field values.
class Deletable(models.Model):
deleted = models.BooleanField(default=False)
class Meta:
abstract=True
def soft_delete(self):
self.deleted=True
self.save()
class ConcreteModel(Deletable):
a = models.IntegerField()
b = models.IntegerField()
class Meta:
#wrong because there may have been some deleted rows
unique_together=('a', 'b')
What is the best way to enforce the constraint?
Define your unique constraint across one more field: deleted
and your pseudo-unique fields. Then, to represent a soft delete, assign the model's id to deleted
; for undeleted items, assign 0.
With this approach, for undeleted items, since the deleted
field is consistently-valued, the multi-field unique constraint will effectively ignore the value of the deleted
and enforce uniqueness for just the pseudo-unique fields; for deleted items, deleted
will be taken into account, and since it is unique, the constraint will always be satisified - so any number of models with the same pseudo-unique fields' values can coexist.
For example, the following code might be what you're looking for.
class Deletable(models.Model):
deleted = models.IntegerField(default=0)
class Meta:
abstract=True
def soft_delete(self):
self.deleted=self.id
self.save()
class ConcreteModel(Deletable):
a = models.IntegerField()
b = models.IntegerField()
class Meta:
unique_together=('a', 'b', 'deleted')
这篇关于如何执行条件唯一性约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!