Login

RelatedNullFilterSpec: django-admin custom filter all/null/not null/choices

Author:
Codeko
Posted:
October 7, 2010
Language:
Python
Version:
1.2
Score:
1 (after 1 ratings)

A simple django-admin filter to replace standar RelatedFilterSpec with one with the "All"/"Null"/"Not null" options. It applies to all relational fields (ForeignKey, ManyToManyField).

You can put the code in the __init__.py or wherever you want.

The _register_front idea is copied on this snippet

 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
from django.contrib.admin.filterspecs import FilterSpec
from django.db import models
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _

# FilterSpec.register places the new FilterSpec at the back
# of the list. This can be a problem, because the first
# matching FilterSpec is the one used.
def _register_front(cls, test, factory):
    cls.filter_specs.insert(0, (test, factory))

FilterSpec.register_front = classmethod(_register_front)

class RelatedNullFilterSpec(FilterSpec):
    def __init__(self, f, request, params, model, model_admin):
        super(RelatedNullFilterSpec, self).__init__(f, request, params, model, model_admin)
        if isinstance(f, models.ManyToManyField):
            self.lookup_title = f.rel.to._meta.verbose_name
        else:
            self.lookup_title = f.verbose_name
        self.null_lookup_kwarg = '%s__isnull' % f.name
        self.null_lookup_val = request.GET.get(self.null_lookup_kwarg, None)
        rel_name = f.rel.get_related_field().name
        self.lookup_kwarg = '%s__%s__exact' % (f.name, rel_name)
        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
        self.lookup_choices = f.get_choices(include_blank=False)

    def title(self):
        return self.lookup_title

    def choices(self, cl):
        yield {'selected': self.lookup_val is None and self.null_lookup_val is None,
               'query_string': cl.get_query_string({}, [self.lookup_kwarg,self.null_lookup_kwarg]),
               'display': _('All')}
        yield {'selected': self.lookup_val is None and self.null_lookup_val=="True",
               'query_string': cl.get_query_string({self.null_lookup_kwarg:True},[self.lookup_kwarg]),
               'display': _('Null')}
        yield {'selected': self.lookup_val is None and self.null_lookup_val=="False",
               'query_string': cl.get_query_string({self.null_lookup_kwarg:False},[self.lookup_kwarg]),
               'display': _('Not Null')}
        for pk_val, val in self.lookup_choices:
            yield {'selected': self.lookup_val == smart_unicode(pk_val),
                   'query_string': cl.get_query_string({self.lookup_kwarg: pk_val},[self.null_lookup_kwarg]),
                   'display': val}

FilterSpec.register_front(lambda f: bool(f.rel), RelatedNullFilterSpec)

More like this

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

Comments

ahsan (on August 17, 2011):

how to use this ??

#

Cerinin (on October 7, 2011):

How do you use this? It's pretty useless without some explanation.

#

Please login first before commenting.