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
.
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.
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.
The accepted solution works great for me but I needed a little bit more flexibility, so I ended up extending the changelist view to add in a custom queryset parameter. I can now configure my default queryset/filter as such and it can still be modified by using a different filter (get parameters):
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)