如何在Django Admin中实现大小写不敏感的SimpleListFilter过滤
Django Admin 实现大小写不敏感的首字母过滤
自定义SimpleListFilter解决重复选项问题
不用改数据库存储,直接重写SimpleListFilter的核心方法,统一首字母大小写并合并统计:
from django.contrib import admin from django.db.models import Func, Count, CharField from .models import Ingredient # 替换成你的食材模型 class FirstLetterFilter(admin.SimpleListFilter): title = '食材首字母' parameter_name = 'first_letter' def lookups(self, request, model_admin): # 提取首字母并统一转为大写,分组统计数量 letters = model_admin.model.objects.annotate( # 取名称的第一个字符 first_letter=Func( 'name', function='LEFT', template='%(function)s(%(expressions)s, 1)', output_field=CharField() ), # 转成大写,避免大小写拆分 upper_first_letter=Func('first_letter', function='UPPER') ).values('upper_first_letter').annotate(count=Count('id')).order_by('upper_first_letter') # 生成合并后的过滤选项 return [ (letter['upper_first_letter'], f"{letter['upper_first_letter']}({letter['count']})") for letter in letters ] def queryset(self, request, queryset): value = self.value() if value: # 用__istartswith实现大小写不敏感的开头匹配 return queryset.filter(name__istartswith=value) return queryset
在Admin类中启用过滤器
把自定义过滤器加到对应模型的Admin配置里:
@admin.register(Ingredient) class IngredientAdmin(admin.ModelAdmin): list_display = ('name',) # 替换成你的显示字段 list_filter = (FirstLetterFilter,) # 加入自定义过滤器
核心逻辑说明
lookups方法通过数据库函数统一首字母为大写,再分组统计,彻底避免大小写导致的重复选项。queryset方法用__istartswith查询,确保选中某个字母时,不管原名称是大写还是小写开头的食材都会被筛选出来。- 全程不修改数据库里的原始数据,只在过滤逻辑层处理大小写问题,适配所有类似场景。
内容的提问来源于stack exchange,提问作者moonsund
相关产品推荐
相关产品推荐

