Ticket #5833: custom_filterspecs_plus_fieldless.patch
File custom_filterspecs_plus_fieldless.patch, 10.1 KB (added by , 17 years ago) |
---|
-
django/contrib/admin/filterspecs.py
diff -r 95bbd099704f -r cbc7231501d2 django/contrib/admin/filterspecs.py
a b 14 14 import datetime 15 15 16 16 class FilterSpec(object): 17 filter_specs = [] 18 def __init__(self, f, request, params, model, model_admin): 19 self.field = f 17 def __init__(self, request, params, model, model_admin): 20 18 self.params = params 21 22 def register(cls, test, factory):23 cls.filter_specs.append((test, factory))24 register = classmethod(register)25 26 def create(cls, f, request, params, model, model_admin):27 for test, factory in cls.filter_specs:28 if test(f):29 return factory(f, request, params, model, model_admin)30 create = classmethod(create)31 19 32 20 def has_output(self): 33 21 return True … … 36 24 raise NotImplementedError() 37 25 38 26 def title(self): 39 r eturn self.field.verbose_name27 raise NotImplementedError() 40 28 41 29 def output(self, cl): 42 30 t = [] … … 51 39 t.append('</ul>\n\n') 52 40 return mark_safe("".join(t)) 53 41 54 class RelatedFilterSpec(FilterSpec): 55 def __init__(self, f, request, params, model, model_admin): 56 super(RelatedFilterSpec, self).__init__(f, request, params, model, model_admin) 57 if isinstance(f, models.ManyToManyField): 58 self.lookup_title = f.rel.to._meta.verbose_name 42 class FieldFilterSpec(FilterSpec): 43 field_filter_specs = [] 44 def __init__(self, request, params, model, model_admin, field): 45 super(FilterSpec, self).__init__(request, params, model, model_admin) 46 self.field = field 47 48 def register(cls, test, factory): 49 cls.field_filter_specs.append((test, factory)) 50 register = classmethod(register) 51 52 def create(cls, request, params, model, model_admin, field): 53 for test, factory in cls.field_filter_specs: 54 if test(field): 55 return factory(request, params, model, model_admin, field) 56 create = classmethod(create) 57 58 def title(self): 59 return self.field.verbose_name 60 61 class RelatedFilterSpec(FieldFilterSpec): 62 def __init__(self, request, params, model, model_admin, field): 63 super(RelatedFilterSpec, self).__init__(request, params, model, model_admin, field) 64 if isinstance(field, models.ManyToManyField): 65 self.lookup_title = field.rel.to._meta.verbose_name 59 66 else: 60 self.lookup_title = f .verbose_name61 self.lookup_kwarg = '%s__%s__exact' % (f .name, f.rel.to._meta.pk.name)67 self.lookup_title = field.verbose_name 68 self.lookup_kwarg = '%s__%s__exact' % (field.name, field.rel.to._meta.pk.name) 62 69 self.lookup_val = request.GET.get(self.lookup_kwarg, None) 63 self.lookup_choices = f .rel.to._default_manager.all()70 self.lookup_choices = field.rel.to._default_manager.all() 64 71 65 72 def has_output(self): 66 73 return len(self.lookup_choices) > 1 … … 77 84 yield {'selected': self.lookup_val == smart_unicode(pk_val), 78 85 'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}), 79 86 'display': val} 87 FieldFilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec) 80 88 81 FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec) 82 83 class ChoicesFilterSpec(FilterSpec): 84 def __init__(self, f, request, params, model, model_admin): 85 super(ChoicesFilterSpec, self).__init__(f, request, params, model, model_admin) 86 self.lookup_kwarg = '%s__exact' % f.name 89 class ChoicesFilterSpec(FieldFilterSpec): 90 def __init__(self, request, params, model, model_admin, field): 91 super(ChoicesFilterSpec, self).__init__(request, params, model, model_admin, field) 92 self.lookup_kwarg = '%s__exact' % field.name 87 93 self.lookup_val = request.GET.get(self.lookup_kwarg, None) 88 94 89 95 def choices(self, cl): … … 94 100 yield {'selected': smart_unicode(k) == self.lookup_val, 95 101 'query_string': cl.get_query_string({self.lookup_kwarg: k}), 96 102 'display': v} 103 FieldFilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec) 97 104 98 FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec) 99 100 class DateFieldFilterSpec(FilterSpec): 101 def __init__(self, f, request, params, model, model_admin): 102 super(DateFieldFilterSpec, self).__init__(f, request, params, model, model_admin) 105 class DateFieldFilterSpec(FieldFilterSpec): 106 def __init__(self, request, params, model, model_admin, field): 107 super(DateFieldFilterSpec, self).__init__(request, params, model, model_admin, field) 103 108 104 109 self.field_generic = '%s__' % self.field.name 105 110 … … 115 120 '%s__month' % self.field.name: str(today.month), 116 121 '%s__day' % self.field.name: str(today.day)}), 117 122 (_('Past 7 days'), {'%s__gte' % self.field.name: one_week_ago.strftime('%Y-%m-%d'), 118 '%s__lte' % f .name: today_str}),123 '%s__lte' % field.name: today_str}), 119 124 (_('This month'), {'%s__year' % self.field.name: str(today.year), 120 '%s__month' % f .name: str(today.month)}),125 '%s__month' % field.name: str(today.month)}), 121 126 (_('This year'), {'%s__year' % self.field.name: str(today.year)}) 122 127 ) 123 128 … … 129 134 yield {'selected': self.date_params == param_dict, 130 135 'query_string': cl.get_query_string(param_dict, [self.field_generic]), 131 136 'display': title} 137 FieldFilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec) 132 138 133 FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec) 134 135 class BooleanFieldFilterSpec(FilterSpec): 136 def __init__(self, f, request, params, model, model_admin): 137 super(BooleanFieldFilterSpec, self).__init__(f, request, params, model, model_admin) 138 self.lookup_kwarg = '%s__exact' % f.name 139 self.lookup_kwarg2 = '%s__isnull' % f.name 139 class BooleanFieldFilterSpec(FieldFilterSpec): 140 def __init__(self, request, params, model, model_admin, field): 141 super(BooleanFieldFilterSpec, self).__init__(request, params, model, model_admin, field) 142 self.lookup_kwarg = '%s__exact' % field.name 143 self.lookup_kwarg2 = '%s__isnull' % field.name 140 144 self.lookup_val = request.GET.get(self.lookup_kwarg, None) 141 145 self.lookup_val2 = request.GET.get(self.lookup_kwarg2, None) 142 146 … … 152 156 yield {'selected': self.lookup_val2 == 'True', 153 157 'query_string': cl.get_query_string({self.lookup_kwarg2: 'True'}, [self.lookup_kwarg]), 154 158 'display': _('Unknown')} 155 156 FilterSpec.register(lambda f: isinstance(f, models.BooleanField) or isinstance(f, models.NullBooleanField), BooleanFieldFilterSpec) 159 FieldFilterSpec.register(lambda f: isinstance(f, models.BooleanField) or isinstance(f, models.NullBooleanField), BooleanFieldFilterSpec) 157 160 158 161 # This should be registered last, because it's a last resort. For example, 159 162 # if a field is eligible to use the BooleanFieldFilterSpec, that'd be much 160 163 # more appropriate, and the AllValuesFilterSpec won't get used for it. 161 class AllValuesFilterSpec(Fi lterSpec):162 def __init__(self, f, request, params, model, model_admin):163 super(AllValuesFilterSpec, self).__init__( f, request, params, model, model_admin)164 self.lookup_val = request.GET.get(f .name, None)165 self.lookup_choices = model_admin.queryset(request).distinct().order_by(f .name).values(f.name)164 class AllValuesFilterSpec(FieldFilterSpec): 165 def __init__(self, request, params, model, model_admin, field): 166 super(AllValuesFilterSpec, self).__init__(request, params, model, model_admin, field) 167 self.lookup_val = request.GET.get(field.name, None) 168 self.lookup_choices = model_admin.queryset(request).distinct().order_by(field.name).values(field.name) 166 169 167 170 def title(self): 168 171 return self.field.verbose_name … … 176 179 yield {'selected': self.lookup_val == val, 177 180 'query_string': cl.get_query_string({self.field.name: val}), 178 181 'display': val} 179 FilterSpec.register(lambda f: True, AllValuesFilterSpec) 182 FieldFilterSpec.register(lambda f: True, AllValuesFilterSpec) 183 -
django/contrib/admin/views/main.py
diff -r 95bbd099704f -r cbc7231501d2 django/contrib/admin/views/main.py
a b 1 1 from django import template 2 from django.contrib.admin.filterspecs import Fi lterSpec2 from django.contrib.admin.filterspecs import FieldFilterSpec 3 3 from django.contrib.admin.options import IncorrectLookupParameters 4 4 from django.contrib.admin.views.decorators import staff_member_required 5 5 from django.core.exceptions import ObjectDoesNotExist … … 158 158 def get_filters(self, request): 159 159 filter_specs = [] 160 160 if self.list_filter and not self.opts.one_to_one_field: 161 filter_fields = [self.lookup_opts.get_field(field_name) for field_name in self.list_filter] 162 for f in filter_fields: 163 spec = FilterSpec.create(f, request, self.params, self.model, self.model_admin) 161 for item in self.list_filter: 162 if callable(item): 163 spec = item( 164 request, self.params, self.model, self.model_admin 165 ) 166 else: 167 if type(item) is tuple: 168 (name, factory) = item 169 else: 170 name = item 171 factory = FieldFilterSpec.create 172 f = self.lookup_opts.get_field(name) 173 spec = factory( 174 request, self.params, self.model, self.model_admin, f 175 ) 164 176 if spec and spec.has_output(): 165 177 filter_specs.append(spec) 166 178 return filter_specs, bool(filter_specs)