Django admin list_filter - 过滤字段为空(无或空字符串"")

Max*_*ore 10 django django-admin

在models.py我有:

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

在admin.py中:

class UserAdmin(admin.ModelAdmin):
    list_filter = ['image']

admin.site.register(User, UserAdmin)
Run Code Online (Sandbox Code Playgroud)

我只是想通过图像或不图像来过滤用户(空或空字符串)

但是django显示按图片urls =)过滤

有没有办法使list_filter = ['image']表现像布尔字段?

建议大!

Max*_*ore 15

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]
Run Code Online (Sandbox Code Playgroud)


Dyl*_*ung 7

从 Django 3.1 开始,您可以EmptyFieldListFilter按如下方式使用:

list_filter = (
    ("my_fk_field", admin.EmptyFieldListFilter),
)
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅文档。另请参阅发行说明

如果您需要对其进行自定义或向后移植,可以在此处获得该代码。


K.H*_*.H. 6

根据 MaxCore 的回答,我创建了可用于修改标题和参数名称的自定义类:

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"
Run Code Online (Sandbox Code Playgroud)