app/django/contrib/admin/filterspecs.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
    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):