自定义管理页面 - list_filter 第一个字母

custom admin page - list_filter by first letter

我有 class 用于自定义管理子页面:

class SerchPlaceAdmin(admin.ModelAdmin):
    list_filter = ('nameplace',)

nameplacemodels.CharField。我想按首字母过滤记录。请查看 printscreen

这应该适合您,请参阅 docs 了解更多信息:

from django.contrib import admin
from django.utils.translation import ugettext_lazy as _


class FirstLetterListFilter(admin.SimpleListFilter):
    title = _('First letter')

    # Parameter for the filter that will be used in the URL query.
    parameter_name = 'letter'

    def lookups(self, request, model_admin):
        return (
            ('A', _('A')),
            ('B', _('B'))
        )

    def queryset(self, request, queryset):
        return queryset.filter(nameplace__startswith=self.value())

class SerchPlaceAdmin(admin.ModelAdmin):
    list_filter = (FirstLetterListFilter,)

接受的答案对我来说有一个问题:它会破坏未过滤的视图。这是由下面 queryset 方法中的 if 子句修复的。

此外,下面的代码搜索不区分大小写,只显示 return 结果的字母,包括计数。

class FirstLetterFilter(SimpleListFilter):
    # Human-readable title which will be displayed in the
    # right admin sidebar just above the filter options.
    title = 'First Letter'

    # Parameter for the filter that will be used in the URL query.
    parameter_name = 'letter'
    letters = list(string.ascii_uppercase)

    def lookups(self, request, model_admin):
        qs = model_admin.get_queryset(request)
        lookups = []
        for letter in self.letters:
            count = qs.filter(name__istartswith=letter).count()
            if count:
                lookups.append((letter, '{} ({})'.format(letter, count)))
        return lookups

    def queryset(self, request, queryset):
        """
        Returns the filtered queryset based on the value
        provided in the query string and retrievable via
        `self.value()`.
        """
        filter_val = self.value()
        if filter_val in self.letters:
            return queryset.filter(name__istartswith=self.value())

当然,对于大表,我建议将第一个字母提取到它自己的列中并在其上放置一个索引(不区分大小写)。

对于适合不区分大小写搜索的不区分大小写的排序,将其添加到您的 ModelAdmin:

class MyModelAdmin(ModelAdmin):
    list_display = ('name',)
    search_fields = ['name']

    def get_ordering(self, request):
        return [Lower('name')]