Django Admin Filter __in query string

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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)

More like this

  1. Null Field Admin Filter by bcurtu 5 years, 3 months ago
  2. Number generator to autofill a field by pizte 3 years, 9 months ago
  3. Group results by a range of values in admin sidebar by wgollino 6 years, 2 months ago
  4. nofollow filter by svetlyak 6 years, 9 months ago
  5. Add delete buttons to admin changelist by kylefox 6 years, 11 months ago

Comments

(Forgotten your password?)