2012-09-10 555 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)