# File: filterspecs.py from django.db import models from django.contrib.admin.util import get_model_from_relation from django.contrib.admin.filterspecs import FilterSpec from django.utils.translation import ugettext as _ class OneToOneExistsFilterSpec(FilterSpec): def __init__(self, f, request, params, model, model_admin, field_path=None): super(OneToOneExistsFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path) other_model = get_model_from_relation(f) if isinstance(f, (models.ManyToManyField, models.related.RelatedObject)): # no direct field on this model, get name from other model self.lookup_title = other_model._meta.verbose_name else: self.lookup_title = f.verbose_name # use field name self.lookup_kwarg = '%s__isnull' % self.field_path self.lookup_val = request.GET.get(self.lookup_kwarg, None) def title(self): return self.lookup_title def choices(self, cl): for k, v in ((_('All'), None), (_('Yes'), 'False'), (_('No'), 'True')): yield {'selected': self.lookup_val == v, 'query_string': cl.get_query_string( {self.lookup_kwarg: v}, [self.lookup_kwarg]), 'display': k} # registering the filter FilterSpec.filter_specs.insert(0, (lambda f: getattr(f.field, 'exists_filter', False), OneToOneExistsFilterSpec))