1 """
2 FilterSpec encapsulates the logic for displaying filters in the Django admin.
3 Filters are specified in models with the "list_filter" option.
4
5 Each filter subclass knows how to display a filter for a field that passes a
6 certain test -- e.g. being a DateField or ForeignKey.
7 """
8
9 from django.db import models
10 from django.utils.encoding import smart_unicode, iri_to_uri
11 from django.utils.translation import ugettext as _
12 from django.utils.html import escape
13 from django.utils.safestring import mark_safe
14 import datetime
15
17 filter_specs = []
18 - def __init__(self, f, request, params, model):
19 self.field = f
20 self.params = params
21
24 register = classmethod(register)
25
26 - def create(cls, f, request, params, model):
30 create = classmethod(create)
31
34
36 raise NotImplementedError()
37
40
42 t = []
43 if self.has_output():
44 t.append(_(u'<h3>By %s:</h3>\n<ul>\n') % escape(self.title()))
45
46 for choice in self.choices(cl):
47 t.append(u'<li%s><a href="%s">%s</a></li>\n' % \
48 ((choice['selected'] and ' class="selected"' or ''),
49 iri_to_uri(choice['query_string']),
50 choice['display']))
51 t.append('</ul>\n\n')
52 return mark_safe("".join(t))
53
80
81 FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec)
82
84 - def __init__(self, f, request, params, model):
88
90 yield {'selected': self.lookup_val is None,
91 'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
92 'display': _('All')}
93 for k, v in self.field.choices:
94 yield {'selected': smart_unicode(k) == self.lookup_val,
95 'query_string': cl.get_query_string({self.lookup_kwarg: k}),
96 'display': v}
97
98 FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec)
99
101 - def __init__(self, f, request, params, model):
102 super(DateFieldFilterSpec, self).__init__(f, request, params, model)
103
104 self.field_generic = '%s__' % self.field.name
105
106 self.date_params = dict([(k, v) for k, v in params.items() if k.startswith(self.field_generic)])
107
108 today = datetime.date.today()
109 one_week_ago = today - datetime.timedelta(days=7)
110 today_str = isinstance(self.field, models.DateTimeField) and today.strftime('%Y-%m-%d 23:59:59') or today.strftime('%Y-%m-%d')
111
112 self.links = (
113 (_('Any date'), {}),
114 (_('Today'), {'%s__year' % self.field.name: str(today.year),
115 '%s__month' % self.field.name: str(today.month),
116 '%s__day' % self.field.name: str(today.day)}),
117 (_('Past 7 days'), {'%s__gte' % self.field.name: one_week_ago.strftime('%Y-%m-%d'),
118 '%s__lte' % f.name: today_str}),
119 (_('This month'), {'%s__year' % self.field.name: str(today.year),
120 '%s__month' % f.name: str(today.month)}),
121 (_('This year'), {'%s__year' % self.field.name: str(today.year)})
122 )
123
126
128 for title, param_dict in self.links:
129 yield {'selected': self.date_params == param_dict,
130 'query_string': cl.get_query_string(param_dict, [self.field_generic]),
131 'display': title}
132
133 FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec)
134
136 - def __init__(self, f, request, params, model):
142
145
147 for k, v in ((_('All'), None), (_('Yes'), '1'), (_('No'), '0')):
148 yield {'selected': self.lookup_val == v and not self.lookup_val2,
149 'query_string': cl.get_query_string({self.lookup_kwarg: v}, [self.lookup_kwarg2]),
150 'display': k}
151 if isinstance(self.field, models.NullBooleanField):
152 yield {'selected': self.lookup_val2 == 'True',
153 'query_string': cl.get_query_string({self.lookup_kwarg2: 'True'}, [self.lookup_kwarg]),
154 'display': _('Unknown')}
155
156 FilterSpec.register(lambda f: isinstance(f, models.BooleanField) or isinstance(f, models.NullBooleanField), BooleanFieldFilterSpec)
157
158
159
160
162 - def __init__(self, f, request, params, model):
166
169
179 FilterSpec.register(lambda f: True, AllValuesFilterSpec)
180