Django admin list_filter - filter field by is empty (None or empty string "")

Based on MaxCore's answer, I created customised class that I can use to modify title and parameter name:

from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from django.db.models import Q

class NotNullFilter(admin.SimpleListFilter):
    title = _('Filter title not set')

    parameter_name = 'parameter name not set'

    def lookups(self, request, model_admin):

        return (
            ('not_null', _('Not empty only')),
            ('null', _('Empty only')),
        )

    def queryset(self, request, queryset):

        if self.value() == 'not_null':
            is_null_false = {
                self.parameter_name + "__isnull": False
            }
            exclude = {
                self.parameter_name: ""
            }
            return queryset.filter(**is_null_false).exclude(**exclude)

        if self.value() == 'null':
            is_null_true = {
                self.parameter_name + "__isnull": True
            }
            param_exact = {
                self.parameter_name + "__exact": ""
            }
            return queryset.filter(Q(**is_null_true) | Q(**param_exact))


class YoutubeNotNullFilter(NotNullFilter):
    title = "Youtube"
    parameter_name = "youtube_videoid"

As of Django 3.1, you can use EmptyFieldListFilter as follows:

list_filter = (
    ("my_fk_field", admin.EmptyFieldListFilter),
)

See the docs for details. See the release notes as well.

The code is available here, if you need to customize it or backport it.


admin.py

class ImageListFilter(admin.SimpleListFilter):

    title = _('Has photo')

    parameter_name = 'has_photo'

    def lookups(self, request, model_admin):

        return (
            ('yes', _('Yes')),
            ('no',  _('No')),
        )

    def queryset(self, request, queryset):

        if self.value() == 'yes':
            return queryset.filter(image__isnull=False).exclude(image='')

        if self.value() == 'no':
            return queryset.filter(Q(image__isnull=True) | Q(image__exact=''))


class UserAdmin(admin.ModelAdmin):

    list_filter = [ImageListFilter]