13 from django.utils.safestring import mark_safe |
13 from django.utils.safestring import mark_safe |
14 import datetime |
14 import datetime |
15 |
15 |
16 class FilterSpec(object): |
16 class FilterSpec(object): |
17 filter_specs = [] |
17 filter_specs = [] |
18 def __init__(self, f, request, params, model): |
18 def __init__(self, f, request, params, model, model_admin): |
19 self.field = f |
19 self.field = f |
20 self.params = params |
20 self.params = params |
21 |
21 |
22 def register(cls, test, factory): |
22 def register(cls, test, factory): |
23 cls.filter_specs.append((test, factory)) |
23 cls.filter_specs.append((test, factory)) |
24 register = classmethod(register) |
24 register = classmethod(register) |
25 |
25 |
26 def create(cls, f, request, params, model): |
26 def create(cls, f, request, params, model, model_admin): |
27 for test, factory in cls.filter_specs: |
27 for test, factory in cls.filter_specs: |
28 if test(f): |
28 if test(f): |
29 return factory(f, request, params, model) |
29 return factory(f, request, params, model, model_admin) |
30 create = classmethod(create) |
30 create = classmethod(create) |
31 |
31 |
32 def has_output(self): |
32 def has_output(self): |
33 return True |
33 return True |
34 |
34 |
50 choice['display'])) |
50 choice['display'])) |
51 t.append('</ul>\n\n') |
51 t.append('</ul>\n\n') |
52 return mark_safe("".join(t)) |
52 return mark_safe("".join(t)) |
53 |
53 |
54 class RelatedFilterSpec(FilterSpec): |
54 class RelatedFilterSpec(FilterSpec): |
55 def __init__(self, f, request, params, model): |
55 def __init__(self, f, request, params, model, model_admin): |
56 super(RelatedFilterSpec, self).__init__(f, request, params, model) |
56 super(RelatedFilterSpec, self).__init__(f, request, params, model, model_admin) |
57 if isinstance(f, models.ManyToManyField): |
57 if isinstance(f, models.ManyToManyField): |
58 self.lookup_title = f.rel.to._meta.verbose_name |
58 self.lookup_title = f.rel.to._meta.verbose_name |
59 else: |
59 else: |
60 self.lookup_title = f.verbose_name |
60 self.lookup_title = f.verbose_name |
61 self.lookup_kwarg = '%s__%s__exact' % (f.name, f.rel.to._meta.pk.name) |
61 self.lookup_kwarg = '%s__%s__exact' % (f.name, f.rel.to._meta.pk.name) |
79 'display': val} |
79 'display': val} |
80 |
80 |
81 FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec) |
81 FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec) |
82 |
82 |
83 class ChoicesFilterSpec(FilterSpec): |
83 class ChoicesFilterSpec(FilterSpec): |
84 def __init__(self, f, request, params, model): |
84 def __init__(self, f, request, params, model, model_admin): |
85 super(ChoicesFilterSpec, self).__init__(f, request, params, model) |
85 super(ChoicesFilterSpec, self).__init__(f, request, params, model, model_admin) |
86 self.lookup_kwarg = '%s__exact' % f.name |
86 self.lookup_kwarg = '%s__exact' % f.name |
87 self.lookup_val = request.GET.get(self.lookup_kwarg, None) |
87 self.lookup_val = request.GET.get(self.lookup_kwarg, None) |
88 |
88 |
89 def choices(self, cl): |
89 def choices(self, cl): |
90 yield {'selected': self.lookup_val is None, |
90 yield {'selected': self.lookup_val is None, |
96 'display': v} |
96 'display': v} |
97 |
97 |
98 FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec) |
98 FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec) |
99 |
99 |
100 class DateFieldFilterSpec(FilterSpec): |
100 class DateFieldFilterSpec(FilterSpec): |
101 def __init__(self, f, request, params, model): |
101 def __init__(self, f, request, params, model, model_admin): |
102 super(DateFieldFilterSpec, self).__init__(f, request, params, model) |
102 super(DateFieldFilterSpec, self).__init__(f, request, params, model, model_admin) |
103 |
103 |
104 self.field_generic = '%s__' % self.field.name |
104 self.field_generic = '%s__' % self.field.name |
105 |
105 |
106 self.date_params = dict([(k, v) for k, v in params.items() if k.startswith(self.field_generic)]) |
106 self.date_params = dict([(k, v) for k, v in params.items() if k.startswith(self.field_generic)]) |
107 |
107 |
131 'display': title} |
131 'display': title} |
132 |
132 |
133 FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec) |
133 FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec) |
134 |
134 |
135 class BooleanFieldFilterSpec(FilterSpec): |
135 class BooleanFieldFilterSpec(FilterSpec): |
136 def __init__(self, f, request, params, model): |
136 def __init__(self, f, request, params, model, model_admin): |
137 super(BooleanFieldFilterSpec, self).__init__(f, request, params, model) |
137 super(BooleanFieldFilterSpec, self).__init__(f, request, params, model, model_admin) |
138 self.lookup_kwarg = '%s__exact' % f.name |
138 self.lookup_kwarg = '%s__exact' % f.name |
139 self.lookup_kwarg2 = '%s__isnull' % f.name |
139 self.lookup_kwarg2 = '%s__isnull' % f.name |
140 self.lookup_val = request.GET.get(self.lookup_kwarg, None) |
140 self.lookup_val = request.GET.get(self.lookup_kwarg, None) |
141 self.lookup_val2 = request.GET.get(self.lookup_kwarg2, None) |
141 self.lookup_val2 = request.GET.get(self.lookup_kwarg2, None) |
142 |
142 |
157 |
157 |
158 # This should be registered last, because it's a last resort. For example, |
158 # This should be registered last, because it's a last resort. For example, |
159 # if a field is eligible to use the BooleanFieldFilterSpec, that'd be much |
159 # if a field is eligible to use the BooleanFieldFilterSpec, that'd be much |
160 # more appropriate, and the AllValuesFilterSpec won't get used for it. |
160 # more appropriate, and the AllValuesFilterSpec won't get used for it. |
161 class AllValuesFilterSpec(FilterSpec): |
161 class AllValuesFilterSpec(FilterSpec): |
162 def __init__(self, f, request, params, model): |
162 def __init__(self, f, request, params, model, model_admin): |
163 super(AllValuesFilterSpec, self).__init__(f, request, params, model) |
163 super(AllValuesFilterSpec, self).__init__(f, request, params, model, model_admin) |
164 self.lookup_val = request.GET.get(f.name, None) |
164 self.lookup_val = request.GET.get(f.name, None) |
165 self.lookup_choices = model._meta.admin.manager.distinct().order_by(f.name).values(f.name) |
165 self.lookup_choices = model_admin.queryset(request).distinct().order_by(f.name).values(f.name) |
166 |
166 |
167 def title(self): |
167 def title(self): |
168 return self.field.verbose_name |
168 return self.field.verbose_name |
169 |
169 |
170 def choices(self, cl): |
170 def choices(self, cl): |