I know I already managed to do this but can't remember how nor I can't find any documentation about this..
How can apply a filter by default on a object list view in the admin ?
I have an app which list quotes and those quotes have a status (ex: accepted, rejected, on hold ..).
I want the filter set on status='accepted' by default that is..
Django allows the user of the admin site to filter the instances of a Model by adding the list_filter attribute to your ModelAdmin objects. You can find more information about the Django's filtering utilities in the official documentation, in the Django Admin Site section.
For Django 1.4-1.7, list_filter allows you to use a subclass of SimpleListFilter . It should be possible to create a simple list filter that lists the values you want. If you can't upgrade from Django 1.3, you'd need to use the internal, and undocumented, FilterSpec api.
Run 'python manage.py migrate' to apply them. Username (leave blank to use 'chatru'): admin Email address: [email protected] Password: Password (again): The password is too similar to the username.
A bit more reusable approach:
class DefaultFilterMixIn(admin.ModelAdmin): def changelist_view(self, request, *args, **kwargs): from django.http import HttpResponseRedirect if self.default_filters: try: test = request.META['HTTP_REFERER'].split(request.META['PATH_INFO']) if test and test[-1] and not test[-1].startswith('?'): url = reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.module_name)) filters = [] for filter in self.default_filters: key = filter.split('=')[0] if not request.GET.has_key(key): filters.append(filter) if filters: return HttpResponseRedirect("%s?%s" % (url, "&".join(filters))) except: pass return super(DefaultFilterMixIn, self).changelist_view(request, *args, **kwargs)
And then just define a default_filters on your ModelAdmin:
class YourModelAdmin(DefaultFilterMixIn): .... default_filters = ('snapshot__exact=0',)
Finally, this is what I was looking for:
def changelist_view(self, request, extra_context=None): if not request.GET.has_key('status__exact'): q = request.GET.copy() q['status__exact'] = '1' request.GET = q request.META['QUERY_STRING'] = request.GET.urlencode() return super(SoumissionAdmin,self).changelist_view(request, extra_context=extra_context)
The other way, with the queryset method in the admin class does not work. In fact it does filter the results, but it leaves the filter functionality broken.
The solution I've found is not perfect either, it's not possible when using it to select the "All/ filter. In my case it's not dramatic and it will be good enough though..
You can override the queryset
class QuoteAdmin(admin.ModelAdmin):
def get_queryset(self, request):
return super(QuoteAdmin,self).get_queryset(request).filter(status="accepted")
However by overriding the queryset you won't ever be able to view quotes that do not have status "accepted".
Alternatively, you can link to the following URL, adding the filter to the GET parameters.
/admin/myapp/quote/?status=accepted
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With