Login

Django Admin Filter __in query string

Author:
justhamade
Posted:
April 23, 2013
Language:
Python
Version:
1.4
Score:
0 (after 0 ratings)

A hack to add in ability to links generated in the Django Admin Filter which will add and remove values instead of only allowing to filter a single value per field. Example ?age_groupin=under25%2C25-35

 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. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

Please login first before commenting.