我结束了使用the top solution here,以及this snippet的混合物。
但是,我不得不稍微调整片段,放下字段类型限制并添加最近在1.3中添加的新field_path。
from django.contrib.admin.filterspecs import FilterSpec
from django.db import models
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
class NullFilterSpec(FilterSpec):
#fields = (models.CharField, models.IntegerField, models.FileField)
@classmethod
def test(cls, field):
#return field.null and isinstance(field, cls.fields) and not field._choices
return field.null and not field._choices
#test = classmethod(test)
def __init__(self, f, request, params, model, model_admin, field_path=None):
super(NullFilterSpec, self).__init__(f, request, params, model, model_admin, field_path)
self.lookup_kwarg = '%s__isnull' % f.name
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
def choices(self, cl):
# bool(v) must be False for IS NOT NULL and True for IS NULL, but can only be a string
for k, v in ((_('All'), None), (_('Has value'), ''), (_('Omitted'), '1')):
yield {
'selected' : self.lookup_val == v,
'query_string' : cl.get_query_string({self.lookup_kwarg : v}),
'display' : k
}
# Here, we insert the new FilterSpec at the first position, to be sure
# it gets picked up before any other
FilterSpec.filter_specs.insert(0,
# If the field has a `profilecountry_filter` attribute set to True
# the this FilterSpec will be used
(lambda f: getattr(f, 'isnull_filter', False), NullFilterSpec)
)
在1.4有''BooleanFieldListFilter''这将默认执行此操作。 ''list_filter =(('myfield',BooleanFieldListFilter),'other_field','other_field2')''。在非布尔字段中,它可以达到与null/not null相同的效果。 –
@KyleMacFarlane虽然 – Kos
似乎不适用于DateTime字段使用1.6它看起来不适用于ForeignKeys。 –