2010-03-22 82 views
20

我已經爲模型添加了「取消」字段,有沒有辦法將模型默認查詢修改爲像cancel = False這樣的東西?而不必修改我所有的過濾/排除查詢?在django中修改默認查詢集

回答

29

您可以使用自定義模型管理器執行此操作,並覆蓋get_queryset函數始終過濾cancel = False。

class CustomManager(models.Manager): 
    def get_queryset(self): 
     return super(CustomManager, self).get_queryset().filter(canceled=False) 

class MyModel(models.Model): 
    # Blah blah 
    objects = CustomManager() 

然後,當調用MyModel.objects.all()時,它將始終排除取消的對象。這裏是一篇博文,我發現這個主題很有幫助。 http://www.b-list.org/weblog/2006/aug/18/django-tips-using-properties-models-and-managers/

編輯: 或許有一個自定義的經理更好的方法是將其附加到另一個屬性,不是對象等,如:

class MyModel(models.Model): 
    # Blah blah 
    active = CustomManager() 

而在你的意見你的查詢看起來像MyModel.active.all()

EDIT2: 對於現代版本的django,更新了從get_query_setget_queryset的拼寫方法。

+2

你必須非常非常小心,重寫默認管理器就是這樣。在這種特殊情況下,一旦項目被取消,您將無法通過filter()/ get()找到它。 – 2010-03-22 18:08:49

+1

同意。我通常會補充這種方法,如果給定pk,則重寫get()不使用此過濾器。您可能還想更改管理查詢集以返回所有包括取消。但是,如果你很少想在你的查詢中取消項目,這可能是一個合理的方法。 – 2010-03-22 18:25:55

+1

嗨,有沒有辦法修改get_query_set的行爲來使用其他參數,即從某處傳遞,或使用全局變量,如當前登錄用戶信息?謝謝! – ultrajohn 2012-06-10 21:39:04

4

你可以寫自定義query manager,但我不認爲這是正確的路要走。這會爲過濾器提供隱含的隱藏條件,從而導致代碼無法讀取。請記住Python的禪宗:Explicit is better than implicit。檢測地點,您需要添加取消= False,只需添加此,這是您應該這樣做的方式。

+5

我強烈反對。那麼,什麼是定製管理者?關於'not_cancelled = CustomManager()'然後使用MyModel.not_cancelled.all()隱含了什麼? – jonwd7 2010-03-23 04:28:38