2012-09-10 53 views
46

我的一個模型都有一個刪除標誌,它被用來在全球範圍內隱藏的對象:覆蓋默認查詢集

class NondeletedManager(models.Manager): 
    """Returns only objects which haven't been deleted""" 

    def get_query_set(self): 
     return super(NondeletedManager, self).get_query_set().exclude(deleted=True) 

class Conversation(BaseModel): 
    ... 
    deleted = models.BooleanField(default=False) 
    objects = NondeletedManager() 
    all_conversations = models.Manager() # includes deleted conversations 

我如何可以覆蓋Django管理模塊用於包括刪除對話的默認查詢集?

+0

您是否真的需要這些簡單查詢的自定義管理器? –

+2

是的,刪除的對象應該被普遍忽略(管理頁面除外),所以設置默認值是有意義的。 –

回答

86

您可以在您的模型管理員類中使用overrideget_queryset方法。

class MyModelAdmin(admin.ModelAdmin): 
    def get_queryset(self, request): 
     qs = super(MyModelAdmin, self).get_queryset(request) 
     if request.user.is_superuser: 
      return qs 
     return qs.filter(author=request.user) 

注意在Django < = 1.5的方法被命名只是queryset

+2

在這種情況下如何工作?我可以修改由'ModelAdmin.queryset'創建的查詢集以包含已刪除的對象嗎?我不想自己構建查詢集而不是調用超類。 –

+0

看看我的答案,看看我的意思。是否有完全重新實現該功能的替代方案? –

+3

它有助於將答案實際放在答案中,而不僅僅是連接。現在這個鏈接已經死了,所以我會更新來給出解釋。 – Dan

2

是什麼錯下列要求:

class Conversation(BaseModel): 
    ... 
    deleted = models.BooleanField(default=False) 
    objects = models.Manager() # includes deleted conversations 
    nondeleted_conversations = NondeletedManager() 

所以在自己的應用程序/項目,可以使用Conversation.nondeleted_conversations(),讓內置的管理應用程序做的事情。

+1

我忽略了任何地方刪除的對象*但*管理頁面,所以我認爲這應該是默認值。此外,通過這種方式,我不需要通過添加刪除對話的功能來更新舊版代碼。 –

7

Konrad是正確的,但這比文檔中給出的示例更困難。

刪除的會話不能包含在已排除它們的查詢集中。所以我沒有看到除了重新實現admin.ModelAdmin.queryset之外的選項。

class ConversationAdmin (admin.ModelAdmin): 

    def queryset (self, request): 
     qs = Conversation.all_conversations 
     ordering = self.get_ordering(request) 
     if ordering: 
      qs = qs.order_by(*ordering) 
     return qs 
+0

我不認爲這有什麼問題。使用兩名經理人員是一條路。但是,確實如此,Django管理員可以提供一個鉤子,以便您不必重新實現排序部分。 –

1

接受的解決方案的偉大工程,爲我,但我需要更多一點的靈活性,所以我結束了擴展變更列表視圖中的自定義查詢集參數添加。我現在可以配置我的默認查詢集/過濾器,它仍然可以通過使用不同的過濾器(獲取參數)進行修改:

def changelist_view(self, request, extra_context=None): 
    if len(request.GET) == 0 : 
     q = request.GET.copy() 
     q['status__gt'] = 4 
     request.GET = q 
     request.META['QUERY_STRING'] = request.GET.urlencode() 

    return super(WorksheetAdmin,self).changelist_view(request, extra_context=extra_context)