繁体   English   中英

Django unique_together并将对象标记为“已删除”

[英]Django unique_together and flagging objects as “deleted”

我正在实现“在Django中标记删除”中讨论的第一个选项,也就是说,当一个对象不再处于活动状态时,我设置了一个布尔值来将其标记为非活动状态。

我使用此方法的具体原因是,虽然该对象不再处于活动状态,但它仍可以在各种记录和报告输出中引用和显示。 我不希望Django的涟漪删除删除旧记录。

我该如何强制执行活动对象的唯一性?

最初,我认为我应该使用unique_together来强制执行数据库级别的约束。 这样可以正常工作,直到我删除一个对象,此时添加一个具有相同名称的新活动对象违反了唯一性要求。 我可以简单地将对象重新标记为活动对象,但实际上我想要一个新对象。

我正在寻找能让我说出“当活跃=真实时独特在一起”之类的东西。 我可以在模型创建代码中强制执行此操作,但似乎在数据库级别强制执行它是一个更好的主意。

关于哪一种是最佳方法的任何建议? 有更好的建议吗?

注意:django-reversion很酷,但完全不适用于我的应用程序,因为我需要不时访问“已删除”的对象。

你可以有一个独特的约束:

class Meta:
     unique_together = ( ('name', 'active'),)

但是,这意味着您只能拥有一个具有相同名称的活动对象和一个非活动对象。

如果激活NullBooleanField,则可以将NULL设置为active,并使(IIRC)具有无限数量的具有相同名称的非活动对象。 至少PostgreSQL将NULL值解释为约束的一部分,因为它不会破坏约束。

我想我明白你来自哪里,当你说这个unique together应该留在数据库层面。 在理论上最好的情况下,最好的设计是不依赖于理解unique together的基础DB强制执行的设计,而是表现为该约束是该表的永久规则。

根据这个想法,如果活动/非活动之间的区别发生在“桌面级别”而不是某些奇特的模型黑客攻击怎么办?

考虑以下:

class BaseModel(models.Model):
    # all of your fields here
    active = models.BooleanField()


class ActiveModel(BaseModel):    
    class Meta:
        unique_together = ('whatever', 'fields')    

    def make_inactive(self):
        # create a new instance of InactiveModel based on
        # this instances's values, then delete this instance


class InactiveModel(BaseModel):
    def make_active(self):
        # create a new instance of InactiveModel based on
        # this instances's values, then delete this instance

这样,无论何时创建新模型,都可以使用ActiveModel进行创建。 然后,仅对活动模型强制执行unique_together。 要将模型标记为非活动状态,请执行model.make_inactive而不是以前的model.active=False 您仍然可以继续对BaseModel执行查询并访问活动和非活动模型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM