Default filter in Django admin

ha22109 picture ha22109 · May 12, 2009 · Viewed 33.8k times · Source

How can I change the default filter choice from 'ALL'? I have a field named as status which has three values: activate, pending and rejected. When I use list_filter in Django admin, the filter is by default set to 'All' but I want to set it to pending by default.

Answer

Greg picture Greg · May 15, 2013

In order to achieve this and have a usable 'All' link in your sidebar (ie one that shows all rather than showing pending), you'd need to create a custom list filter, inheriting from django.contrib.admin.filters.SimpleListFilter and filtering on 'pending' by default. Something along these lines should work:

from datetime import date

from django.utils.translation import ugettext_lazy as _
from django.contrib.admin import SimpleListFilter

class StatusFilter(SimpleListFilter):
    title = _('Status')

    parameter_name = 'status'

    def lookups(self, request, model_admin):
        return (
            (None, _('Pending')),
            ('activate', _('Activate')),
            ('rejected', _('Rejected')),
            ('all', _('All')),
        )

    def choices(self, cl):
        for lookup, title in self.lookup_choices:
            yield {
                'selected': self.value() == lookup,
                'query_string': cl.get_query_string({
                    self.parameter_name: lookup,
                }, []),
                'display': title,
            }

    def queryset(self, request, queryset):
        if self.value() in ('activate', 'rejected'):
            return queryset.filter(status=self.value())    
        elif self.value() == None:
            return queryset.filter(status='pending')


class Admin(admin.ModelAdmin): 
    list_filter = [StatusFilter] 

EDIT: Requires Django 1.4 (thanks Simon)