我正在为我的一个项目实现Django模型的软删除系统,并且我遇到了与“软删除”数据冲突的新数据问题。理想情况下,我希望保留已删除的模型和新模型,但也会对现有模型强制执行唯一约束。
所以基本上我希望能够添加唯一的字段,除非删除= True,此时您可以拥有任意数量的字段。有没有办法做到这一点,不涉及手动覆盖我想要软删除的每个模型的保存功能?
答案 0 :(得分:3)
一种解决方案是创建部分唯一索引;也就是说,当某个表达式为真时,该索引仅强制执行唯一约束。
从Django 2.2开始,您可以执行此操作declaratively。它看起来像是:
from django.db.models import Model, Q, UniqueConstraint
class MyModel(Model):
...
class Meta:
constraints = [UniqueConstraint(fields=["field"], condition=Q(is_deleted=False)]
在旧版本中,您需要使用数据迁移创建部分唯一索引。 (有关详细信息,请参阅我的回答here。)
看起来像是:
class Migration(migrations.Migration):
dependencies = [ ... ]
operations = [
migrations.RunSQL("CREATE UNIQUE INDEX my_constraint
ON appname_mymodel (field)
WHERE is_deleted = false")
]
在这种情况下,Django对约束一无所知,因此无法进行任何验证。因此,如果您希望管理员用户在违反约束条件时收到错误消息,则应提供自己的验证。