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