当前位置: 首页 > 知识库问答 >
问题:

Django中具有唯一约束的软删除

姬英武
2023-03-14

我有这样布局的模型:

class SafeDeleteModel(models.Model):
    .....
    deleted = models.DateTimeField(editable=False, null=True)
    ......

class MyModel(SafeDeleteModel):
    safedelete_policy = SOFT_DELETE

    field1 = models.CharField(max_length=200)
    field2 = models.CharField(max_length=200)
    field3 = models.ForeignKey(MyModel3)
    field4 = models.ForeignKey(MyModel4)
    field5 = models.ForeignKey(MyModel5)

    class Meta:
        unique_together = [['field2', 'field3', 'field4', 'deleted'],]

这里的场景是我永远不希望用户删除数据。相反,删除只会隐藏记录。但是,我仍然希望所有非软删除的记录都遵循唯一的键约束。基本上,我希望有尽可能多的重复的已删除记录,但只有一个唯一的未删除记录可以存在。所以我本来想包括“已删除”字段(由django安全删除库提供),但问题是Django的唯一检查因“psycopg2”而失败。完整性错误:重复的键值违反了 ['field2', 'field3', 'field4', '已删除'] 的唯一约束,因为 NULL 不“等于”NULL,并且在 PostgreSQL 中产生假。

有没有办法在我的Django模型布局中强制执行unique_together约束?或者有更好的主意物理删除记录,然后将其移动到存档数据库中,如果用户想要回记录,那么软件将在存档中查找记录并重新创建它?

共有1个答案

林浩漫
2023-03-14

是的,从Django版本2.2开始,可以使用具有条件的独特约束。

请查看此链接中的文档:https://docs.djangoproject.com/en/2.2/ref/models/constraints/#uniqueconstraint

所以你的模型是这样的:

class MyModel(SafeDeleteModel):
    safedelete_policy = SOFT_DELETE

    field1 = models.CharField(max_length=200)
    field2 = models.CharField(max_length=200)
    field3 = models.ForeignKey(MyModel3)
    field4 = models.ForeignKey(MyModel4)
    field5 = models.ForeignKey(MyModel5)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['field2', 'field3', 'field4'],
                condition=Q(deleted=False),
                name='unique_if_not_deleted')
        ]

如果您使用的是没有此功能的旧版本的Django,则可以使用部分唯一索引创建迁移(请在此处查看此问题:Postgresql:条件唯一约束)。

至于你的第二个问题(物理删除记录并将其移动到其他地方会更好吗),这实际上取决于你的应用程序的特征。如果这些软删除不经常发生,并且您的表仍然很小,为了简单起见,我会将记录保留在同一个表中,但是如果表中的记录数开始快速增长并且它们会影响此表上查询的性能,那么您应该将记录移动到其他位置。您必须评估复杂性和性能之间的权衡。

 类似资料:
  • 问题内容: 我尝试删除h2中以前创建为的列的唯一约束。 我试过了: 但是没有成功(如下): 如何正确消除此约束? 顺便一提: 似乎返回正确的输出。 问题答案: 在SQL语言中,标识符名称不能是表达式。您需要运行两个语句: 然后获取标识符名称,并运行该语句

  • 问题内容: 如何使用phpMyAdmin在MySQL表的列上删除“唯一键约束”? 问题答案: 唯一约束也是索引。 首先使用来查找索引的名称。索引的名称存储在该查询结果中调用的列中。 然后,您可以使用DROP INDEX: 或ALTER TABLE语法:

  • CREATE语句中有以下约束: 这些用于删除约束的命令在MySQL中有效,但在H2中无效: 我需要一个在MySQL和H2中都能工作的命令(MySQL在真实环境中使用,H2在单元测试中使用)

  • 问题内容: 在一个假设的场景中,我是没有表创建特权的用户。我想知道表中的列是否具有 UNIQUE CONSTRAINT 。是否可以在 词典中 查找?我将如何处理? 问题答案: 此处给出的两个答案都缺少一种在列上实施唯一性的方法:通过创建 唯一索引 (而不在列上定义唯一约束)。如果您不熟悉此选项,请参见这两个链接(一个,两个)。 除 唯一约束检查 外 ,还应执行此检查: 要检查唯一约束,请使用已经提

  • 问题内容: 我有一张标签列表,按标签顺序显示。为了确保没有两行可以具有相同的等级,它们的值是唯一的: 不管是PostgreSQL还是MySQL,它们都表现出相同的行为。查询可能看起来像。假设该表包含: 现在,假设我想重新排序两个标签,例如Apple在Cow之前排名。最简单的方法是交换其等级值: 没有。也不: 甚至没有: 每次,唯一约束都会在第一行更新时触发,并中止该操作。如果我可以将支票推迟到帐单

  • 我对Postgres Unique约束有问题,该约束包含多个可能包含空值的列。 让我们假设这种情况: Insert将插入('foo',bar')一次和('foo',NULL)两次(尽管直觉告诉它应该插入一次)。 在这种情况下,解决方案非常简单。我可以添加唯一的索引 但是当有更多的列和不同的类型(不仅仅是文本)时,问题就开始了。假设我们有10列,其中9列可以有值。也许我可以用大量的限制来解决它,但这