Este team redactor ha pasado horas investigando la solución a tu búsqueda, te regalamos la resolución de modo que nuestro objetivo es servirte de mucha apoyo.
Solución:
Dado que Django 1.4 trae algunos cambios a los filtros, pensé en ahorrarle a alguien el tiempo que acabo de pasar modificando el código de la respuesta aceptada de Cerin para que funcione con Django 1.4 rc1.
Tengo un modelo que tiene TimeField(null=Verdadero) llamado “iniciado” y quería filtrar por null y no-null valores, por lo que es más o menos el mismo problema que OP.
Entonces, esto es lo que funcionó para mí …
Definido (en realidad incluido) estos en admin.py:
from django.contrib.admin.filters import SimpleListFilter
class NullFilterSpec(SimpleListFilter):
title = u''
parameter_name = u''
def lookups(self, request, model_admin):
return (
('1', _('Has value'), ),
('0', _('None'), ),
)
def queryset(self, request, queryset):
kwargs =
'%s'%self.parameter_name : None,
if self.value() == '0':
return queryset.filter(**kwargs)
if self.value() == '1':
return queryset.exclude(**kwargs)
return queryset
class StartNullFilterSpec(NullFilterSpec):
title = u'Started'
parameter_name = u'started'
Que simplemente los usó en ModelAdmin:
class SomeModelAdmin(admin.ModelAdmin):
list_filter = (StartNullFilterSpec, )
Tengo una versión más simple de la respuesta de frnhr, que en realidad se filtra en __isnull
condición. (Django 1.4+):
from django.contrib.admin import SimpleListFilter
class NullListFilter(SimpleListFilter):
def lookups(self, request, model_admin):
return (
('1', 'Null', ),
('0', '!= Null', ),
)
def queryset(self, request, queryset):
if self.value() in ('0', '1'):
kwargs = '0__isnull'.format(self.parameter_name) : self.value() == '1'
return queryset.filter(**kwargs)
return queryset
Después también:
class StartNullListFilter(NullListFilter):
title = u'Started'
parameter_name = u'started'
y finalmente:
class SomeModelAdmin(admin.ModelAdmin):
list_filter = (StartNullListFilter, )
Personalmente, no me gusta tirar a la basura mi admin.py
con docenas de clases, así que se me ocurrió una función auxiliar de este tipo:
def null_filter(field, title_=None):
class NullListFieldFilter(NullListFilter):
parameter_name = field
title = title_ or parameter_name
return NullListFieldFilter
Que luego puedo aplicar como en:
class OtherModelAdmin(admin.ModelAdmin):
list_filter = (null_filter('somefield'), null_filter('ugly_field', _('Beautiful Name')), )
Después de Django 3.1 puedes usar CampoVacíoListaFiltro:
class MyAdmin(admin.ModelAdmin):
list_filter = (
("model_field", admin.EmptyFieldListFilter),
)