Saltar al contenido

Filtrado del administrador de Django por nulo/no es nulo

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),
    )

valoraciones y comentarios

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *