Index: /home/bcm/wsp/www/django/contrib/admin/filterspecs.py =================================================================== --- /home/bcm/wsp/www/django/contrib/admin/filterspecs.py (revision 1815) +++ /home/bcm/wsp/www/django/contrib/admin/filterspecs.py (working copy) @@ -155,6 +155,24 @@ FilterSpec.register(lambda f: isinstance(f, models.BooleanField) or isinstance(f, models.NullBooleanField), BooleanFieldFilterSpec) + +class NullFilterSpec(FilterSpec): + def __init__(self, f, request, params, model, model_admin): + super(NullFilterSpec, self).__init__(f, request, params, model, model_admin) + self.lookup_kwarg = '%s__isnull' % f.name + self.lookup_val = request.GET.get(self.lookup_kwarg, None) + + def choices(self, cl): + yield {'selected': self.lookup_val is None, + 'query_string': cl.get_query_string({}, [self.lookup_kwarg]), + 'display': _('All')} + for k, v in ((True,_('Null')),('',_('With value'))): + yield {'selected': k == self.lookup_val, + 'query_string': cl.get_query_string({self.lookup_kwarg: k}), + 'display': v} +FilterSpec.register(lambda f: f.null, NullFilterSpec) + + # This should be registered last, because it's a last resort. For example, # if a field is eligible to use the BooleanFieldFilterSpec, that'd be much # more appropriate, and the AllValuesFilterSpec won't get used for it.