This closure lets you quickly produce date-style range filters in the Django Admin interface without having to create a new class for each one.
It follows Python range semantics, with the lower value using a _gte
test and the upper value using an _lt
test.
Here's an example of how I'm using it in one of my projects:
list_filter = ('complete',
('chapters', makeRangeFieldListFilter([
(_('1'), 1, 2),
(_('2 to 10'), 2, 10),
(_('11 to 30'), 11, 30),
(_('31 to 100'), 31, 100),
(_('At least 100'), 100, None),
], nullable=True)),
('word_count', makeRangeFieldListFilter([
(_('Less than 1000'), None, 1000),
(_('1K to 5K'), 1000, 5000),
(_('5K to 10K'), 5000, 10000),
(_('10K to 75K'), 10000, 75000),
(_('75K to 150K'), 75000, 150000),
(_('150K to 300K'), 150000, 300000),
(_('At least 300K'), 300000, None),
], nullable=True)),
('derivatives_count', makeRangeFieldListFilter([
(_('None'), 0, 1),
(_('1 to 5'), 1, 5),
(_('5 to 50'), 5, 50),
(_('50 to 1000'), 50, 1000),
(_('At least 1000'), 1000, None),
])),
'pub_date', 'upd_date')
It is based on code from DateFieldListFilter
and BooleanFieldListFilter
from django.contrib.admin.filters
.
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 | from django.utils.translation import ugettext_lazy as _
from django.contrib.admin import FieldListFilter
def makeRangeFieldListFilter(lookups, nullable=False):
class RangeFieldListFilter(FieldListFilter):
def __init__(self, field, request, params, model, model_admin, field_path):
self.field_generic = '%s__' % field_path
self.range_params = dict([(k, v) for k, v in params.items()
if k.startswith(self.field_generic)])
self.lookup_kwarg_start = '%s__gte' % field_path
self.lookup_kwarg_stop = '%s__lt' % field_path
self.lookup_kwarg_null = '%s__isnull' % field_path
self.links = [ (_('Any value'), {}), ]
for name, start, stop in lookups:
query_params = {}
if start is not None:
query_params[self.lookup_kwarg_start] = str(start)
if stop is not None:
query_params[self.lookup_kwarg_stop] = str(stop)
self.links.append((name, query_params))
if nullable:
self.links.append((_('Unknown'), {
self.lookup_kwarg_null: 'True'
}))
super(RangeFieldListFilter, self).__init__(
field, request, params, model, model_admin, field_path)
def expected_parameters(self):
return [
self.lookup_kwarg_start,
self.lookup_kwarg_stop,
self.lookup_kwarg_null
]
def choices(self, cl):
for title, param_dict in self.links:
yield {
'selected': self.range_params == param_dict,
'query_string': cl.get_query_string(
param_dict, [self.field_generic]),
'display': title,
}
return RangeFieldListFilter
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.