Ticket #8528: nullfilter-11627.diff

File nullfilter-11627.diff, 3.5 KB (added by Ben Davis, 15 years ago)
  • django/contrib/admin/filterspecs.py

     
    6060            self.lookup_title = f.verbose_name
    6161        rel_name = f.rel.get_related_field().name
    6262        self.lookup_kwarg = '%s__%s__exact' % (f.name, rel_name)
     63        self.lookup_null_kwarg = '%s__isnull' % (f.name)
    6364        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
     65        self.lookup_null = request.GET.get(self.lookup_null_kwarg, None)
    6466        self.lookup_choices = f.get_choices(include_blank=False)
    6567
    6668    def has_output(self):
     
    7072        return self.lookup_title
    7173
    7274    def choices(self, cl):
    73         yield {'selected': self.lookup_val is None,
    74                'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
     75        yield {'selected': self.lookup_val is None and not self.lookup_null,
     76               'query_string': cl.get_query_string({}, [self.lookup_kwarg, self.lookup_null_kwarg]),
    7577               'display': _('All')}
    7678        for pk_val, val in self.lookup_choices:
    7779            yield {'selected': self.lookup_val == smart_unicode(pk_val),
    78                    'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}),
     80                   'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}, [self.lookup_null_kwarg]),
    7981                   'display': val}
     82        if self.field.null:
     83            yield {'selected': self.lookup_null,
     84                   'query_string': cl.get_query_string({self.lookup_null_kwarg: 'True'}, [self.lookup_kwarg]),
     85                   'display': '(None)'}
    8086
    8187FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec)
    8288
     
    162168    def __init__(self, f, request, params, model, model_admin):
    163169        super(AllValuesFilterSpec, self).__init__(f, request, params, model, model_admin)
    164170        self.lookup_val = request.GET.get(f.name, None)
     171        self.lookup_null = request.GET.get(f.name + '__isnull', None)
    165172        self.lookup_choices = model_admin.queryset(request).distinct().order_by(f.name).values(f.name)
    166173
    167174    def title(self):
    168175        return self.field.verbose_name
    169176
    170177    def choices(self, cl):
    171         yield {'selected': self.lookup_val is None,
    172                'query_string': cl.get_query_string({}, [self.field.name]),
     178        yield {'selected': self.lookup_val is None and not self.lookup_null,
     179               'query_string': cl.get_query_string({}, [self.field.name, self.field.name + '__isnull']),
    173180               'display': _('All')}
    174181        for val in self.lookup_choices:
    175             val = smart_unicode(val[self.field.name])
    176             yield {'selected': self.lookup_val == val,
    177                    'query_string': cl.get_query_string({self.field.name: val}),
    178                    'display': val}
    179 FilterSpec.register(lambda f: True, AllValuesFilterSpec)
     182            if val[self.field.name] is None:
     183                yield {'selected': self.lookup_null,
     184                       'query_string': cl.get_query_string({self.field.name + '__isnull': 'True'}, [self.field.name]),
     185                       'display': '(None)'}
     186            else:
     187                val = smart_unicode(val[self.field.name])
     188                yield {'selected': self.lookup_val == val,
     189                       'query_string': cl.get_query_string({self.field.name: val}, [self.field.name + '__isnull']),
     190                       'display': val}
     191FilterSpec.register(lambda f: True, AllValuesFilterSpec)
Back to Top