from django.contrib import admin from django.contrib.admin import ChoicesFieldListFilter from django.contrib.admin.views.main import ChangeList from django.utils.http import urlencode from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import smart_text from .models import Person class MultipleChangeList(ChangeList): def get_query_string(self, new_params=None, remove=None): if new_params is None: new_params = {} if remove is None: remove = [] p = self.params.copy() for r in remove: for k in list(p): if k.startswith(r): del p[k] for k, v in new_params.items(): if v is None: if k in p: del p[k] else: if k in p and '__in' in k: in_list = p[k].split(',') if not v in in_list: in_list.append(v) else: in_list.remove(v) p[k] = ','.join(in_list) else: p[k] = v return '?%s' % urlencode(sorted(p.items())) class MultipleChoicesFieldListFilter(ChoicesFieldListFilter): def __init__(self, field, request, params, model, model_admin, field_path): super(MultipleChoicesFieldListFilter, self).__init__( field, request, params, model, model_admin, field_path) self.lookup_kwarg = '%s__in' % field_path self.lookup_val = request.GET.get(self.lookup_kwarg) def choices(self, cl): yield { 'selected': self.lookup_val is None, 'query_string': cl.get_query_string({}, [self.lookup_kwarg]), 'display': _('All') } for lookup, title in self.field.flatchoices: yield { 'selected': smart_text(lookup) in str(self.lookup_val), 'query_string': cl.get_query_string({ self.lookup_kwarg: lookup}), 'display': title, } class PersonAdmin(model.Admin): list_filter = (('education', MultipleChoicesFieldListFilter),) def get_changelist(self, request, **kwargs): return MultipleChangeList admin.site.register(Person, PersonAdmin)