簡體   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