Override default queryset in Django admin

You can override get_queryset method in your model admin class.

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)

Note in Django<=1.5 the method was named just queryset.


You can do this with a Django proxy model.

# models.py
class UnfilteredConversation(Conversation):
    class Meta:
        proxy = True

    # this will be the 'default manager' used in the Admin, and elsewhere
    objects = models.Manager() 

# admin.py
@admin.register(UnfilteredConversation)
class UnfilteredConversationAdmin(Conversation):
    # regular ModelAdmin stuff here
    ...

Or, if you have an existing ModelAdmin class you want to re-use:

admin.site.register(UnfilteredConversation, ConversationAdmin)

This approach avoids issues that can arise with overriding the default manager on the original Conversation model - because the default manager is also used in ManyToMany relationships and reverse ForeignKey relationships.


Konrad is correct, but this is more difficult than the example given in the documentation.

Deleted conversations can't be included in a queryset that already excludes them. So I don't see an option other than re-implementing admin.ModelAdmin.queryset entirely.

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

What would be so wrong with the following:

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

So in your own apps/projects, you use Conversation.nondeleted_conversations() and let the built-in admin app do it's thing.