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

In models.py, I have:

class User(modals.Model): name = models.CharField(max_length=255) image = models.ImageField(blank=True, null=True) 

And in admin.py:

 class UserAdmin(admin.ModelAdmin): list_filter = ['image'] admin.site.register(User, UserAdmin) 

I just want to filter users by picture or not (empty or empty string)

But Django shows a filter by image urls =)

Is there a way to make list_filter = ['image'] behave like a boolean field?

Thanks so much for the tips!

+9
source share
3 answers

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] 
+14
source

Based on MaxCore's answer, I created a custom class that I can use to change the name and parameter name:

 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" 
+2
source

KH's approach to a base class that can be easily reused was very useful to me. I couldn't get the written example to work, but with a little tweaking, it worked fine (Python 2.7, Django 1.10) to achieve this.

 from django.contrib import admin 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): filter_string = self.parameter_name + '__isnull' if self.value() == 'not_null': is_null_false = { filter_string: False } return queryset.filter(**is_null_false) if self.value() == 'null': is_null_true = { filter_string: True } return queryset.filter(**is_null_true) class YoutubeNotNullFilter(NotNullFilter): title = "Youtube" parameter_name = "youtube_videoid" class SomeVideoClass(admin.ModelAdmin): ... list_filter = [YouTubeNotNullFilter, ...] 
0
source

All Articles