如何执行条件唯一性约束 [英] how to enforce a conditional uniqueness constraint

查看:49
本文介绍了如何执行条件唯一性约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一堆表,其中对象被标记为已删除,而不是实际删除.现在,我要强制执行一个约束,即只有一个具有特定字段值的未删除对象,但是我可以有多个具有相同字段值的已删除对象.

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆