Ticket #3400: 3400-against-7875.patch
File 3400-against-7875.patch, 9.2 KB (added by , 16 years ago) |
---|
-
django/contrib/admin/filterspecs.py
commit 727102a45f6c47eb804441a747d2541a1bcaf5bd Author: Honza Král <Honza.Kral@gmail.com> Date: Mon Jan 28 22:14:49 2008 +0100 Support for lookup separator with list_filter admin option http://code.djangoproject.com/ticket/3400 diff --git a/django/contrib/admin/filterspecs.py b/django/contrib/admin/filterspecs.py index d6a4a0b..2076524 100644
a b import datetime 15 15 16 16 class FilterSpec(object): 17 17 filter_specs = [] 18 def __init__(self, f, request, params, model, model_admin ):18 def __init__(self, f, request, params, model, model_admin, field_path=None): 19 19 self.field = f 20 20 self.params = params 21 self.field_path = field_path or f.name 21 22 22 23 def register(cls, test, factory): 23 24 cls.filter_specs.append((test, factory)) 24 25 register = classmethod(register) 25 26 26 def create(cls, f, request, params, model, model_admin ):27 def create(cls, f, request, params, model, model_admin, field_path=None): 27 28 for test, factory in cls.filter_specs: 28 29 if test(f): 29 return factory(f, request, params, model, model_admin )30 return factory(f, request, params, model, model_admin, field_path=field_path) 30 31 create = classmethod(create) 31 32 32 33 def has_output(self): … … class FilterSpec(object): 52 53 return mark_safe("".join(t)) 53 54 54 55 class RelatedFilterSpec(FilterSpec): 55 def __init__(self, f, request, params, model, model_admin ):56 super(RelatedFilterSpec, self).__init__(f, request, params, model, model_admin )56 def __init__(self, f, request, params, model, model_admin, field_path=None): 57 super(RelatedFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path) 57 58 if isinstance(f, models.ManyToManyField): 58 59 self.lookup_title = f.rel.to._meta.verbose_name 59 60 else: 60 61 self.lookup_title = f.verbose_name 61 self.lookup_kwarg = '%s__%s__exact' % ( f.name, f.rel.to._meta.pk.name)62 self.lookup_kwarg = '%s__%s__exact' % (self.field_path, f.rel.to._meta.pk.name) 62 63 self.lookup_val = request.GET.get(self.lookup_kwarg, None) 63 64 self.lookup_choices = f.rel.to._default_manager.all() 64 65 … … class RelatedFilterSpec(FilterSpec): 81 82 FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec) 82 83 83 84 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.name85 def __init__(self, f, request, params, model, model_admin, field_path=None): 86 super(ChoicesFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path) 87 self.lookup_kwarg = '%s__exact' % self.field_path 87 88 self.lookup_val = request.GET.get(self.lookup_kwarg, None) 88 89 89 90 def choices(self, cl): … … class ChoicesFilterSpec(FilterSpec): 98 99 FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec) 99 100 100 101 class DateFieldFilterSpec(FilterSpec): 101 def __init__(self, f, request, params, model, model_admin ):102 super(DateFieldFilterSpec, self).__init__(f, request, params, model, model_admin )102 def __init__(self, f, request, params, model, model_admin, field_path=None): 103 super(DateFieldFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path) 103 104 104 self.field_generic = '%s__' % self.field .name105 self.field_generic = '%s__' % self.field_path 105 106 106 107 self.date_params = dict([(k, v) for k, v in params.items() if k.startswith(self.field_generic)]) 107 108 … … class DateFieldFilterSpec(FilterSpec): 111 112 112 113 self.links = ( 113 114 (_('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)})115 (_('Today'), {'%s__year' % self.field_path: str(today.year), 116 '%s__month' % self.field_path: str(today.month), 117 '%s__day' % self.field_path: str(today.day)}), 118 (_('Past 7 days'), {'%s__gte' % self.field_path: one_week_ago.strftime('%Y-%m-%d'), 119 '%s__lte' % self.field_path: today_str}), 120 (_('This month'), {'%s__year' % self.field_path: str(today.year), 121 '%s__month' % self.field_path: str(today.month)}), 122 (_('This year'), {'%s__year' % self.field_path: str(today.year)}) 122 123 ) 123 124 124 125 def title(self): … … class DateFieldFilterSpec(FilterSpec): 133 134 FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec) 134 135 135 136 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.name139 self.lookup_kwarg2 = '%s__isnull' % f.name137 def __init__(self, f, request, params, model, model_admin, field_path=None): 138 super(BooleanFieldFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path) 139 self.lookup_kwarg = '%s__exact' % self.field_path 140 self.lookup_kwarg2 = '%s__isnull' % self.field_path 140 141 self.lookup_val = request.GET.get(self.lookup_kwarg, None) 141 142 self.lookup_val2 = request.GET.get(self.lookup_kwarg2, None) 142 143 … … FilterSpec.register(lambda f: isinstance(f, models.BooleanField) or isinstance(f 159 160 # if a field is eligible to use the BooleanFieldFilterSpec, that'd be much 160 161 # more appropriate, and the AllValuesFilterSpec won't get used for it. 161 162 class AllValuesFilterSpec(FilterSpec): 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) 163 def __init__(self, f, request, params, model, model_admin, field_path=None): 164 super(AllValuesFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path) 165 self.lookup_val = request.GET.get(self.field_path, None) 166 #self.lookup_choices = model_admin.queryset(request).distinct().order_by(f.name).values(f.name) 167 self.lookup_choices = model._default_manager.all().distinct().order_by(f.name).values(f.name) 166 168 167 169 def title(self): 168 170 return self.field.verbose_name 169 171 170 172 def choices(self, cl): 171 173 yield {'selected': self.lookup_val is None, 172 'query_string': cl.get_query_string({}, [self.field .name]),174 'query_string': cl.get_query_string({}, [self.field_path]), 173 175 'display': _('All')} 174 176 for val in self.lookup_choices: 175 177 val = smart_unicode(val[self.field.name]) 176 178 yield {'selected': self.lookup_val == val, 177 'query_string': cl.get_query_string({self.field .name: val}),179 'query_string': cl.get_query_string({self.field_path: val}), 178 180 'display': val} 179 181 FilterSpec.register(lambda f: True, AllValuesFilterSpec) -
django/contrib/admin/views/main.py
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index a871867..4c0393d 100644
a b class ChangeList(object): 85 85 def get_filters(self, request): 86 86 filter_specs = [] 87 87 if self.list_filter and not self.opts.one_to_one_field: 88 filter_fields = [self.lookup_opts.get_field(field_name) for field_name in self.list_filter] 89 for f in filter_fields: 90 spec = FilterSpec.create(f, request, self.params, self.model, self.model_admin) 88 lookup_opts = self.lookup_opts 89 for filter_name in self.list_filter: 90 if '__' in filter_name: 91 f = None 92 model = self.model 93 path = filter_name.split('__') 94 for field_name in path[:-1]: 95 f = model._meta.get_field(field_name) 96 model = f.rel.to 97 f = model._meta.get_field(path[-1]) 98 spec = FilterSpec.create(f, request, self.params, model, self.model_admin, field_path=filter_name) 99 else: 100 f = lookup_opts.get_field(filter_name) 101 spec = FilterSpec.create(f, request, self.params, self.model, self.model_admin) 91 102 if spec and spec.has_output(): 92 103 filter_specs.append(spec) 93 104 return filter_specs, bool(filter_specs)