DjangoAdmin的自定义SimpleListFilter子类

时间:2015-06-15 20:48:11

标签: python django

根据Django的文档,我需要一个与描述there非常相似的SimpleListFilter子类:

from datetime import date

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

class DecadeBornListFilter(SimpleListFilter):
    # Human-readable title which will be displayed in the
    # right admin sidebar just above the filter options.
    title = _('decade born')

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

    def lookups(self, request, model_admin):
        """
        Returns a list of tuples. The first element in each
        tuple is the coded value for the option that will
        appear in the URL query. The second element is the
        human-readable name for the option that will appear
        in the right sidebar.
        """
        return (
            ('80s', _('in the eighties')),
            ('90s', _('in the nineties')),
        )

    def queryset(self, request, queryset):
        """
        Returns the filtered queryset based on the value
        provided in the query string and retrievable via
        `self.value()`.
        """
        # Compare the requested value (either '80s' or 'other')
        # to decide how to filter the queryset.
        if self.value() == '80s':
            return queryset.filter(birthday__gte=date(1980, 1, 1),
                                    birthday__lte=date(1989, 12, 31))
        if self.value() == '90s':
            return queryset.filter(birthday__gte=date(1990, 1, 1),
                                    birthday__lte=date(1999, 12, 31))

class PersonAdmin(ModelAdmin):
    list_filter = (DecadeBornListFilter,)

我需要做的唯一改变是在查找方法中,而不是列出几十年,例如80年代或者90年代,想要显示小工具以允许选择一个月和一年,例如JAN ,2000。

在最好的情况下,我想使用两个下拉菜单,一个用于一年,另一个用于月份。另一个替代方案是重新使用日期范围,例如DateRangeFilter,我试过但我无法创建一个新的过滤器类继承DateRangeFilter或在新的过滤器类中使用DateRangeFilter'查找方法。

我正在使用Django 1.7.8,非常感谢任何帮助或提示。

1 个答案:

答案 0 :(得分:1)

您需要两个list_filters,一个用于最大日期,另一个用于最小日期。查询所有不同年份的条目。像这样:

class MaxDateListFilter(SimpleListFilter):
    title = _('maximum date')
    parameter_name = 'max_date'

    def lookups(self, request, model_admin):
        return [(str(year.year), year.year) \
                 for year in Entry.objects.dates('pub_date', 'year')]

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

注意:未经测试的代码。

这适用于小范围。但是对于更大的数据集来说可能不实用。

另一种方法是提供您自己的ModelAdmin.get_search_results并让它接受一些日期搜索查询。完成后,您需要渲染自己的ModelAdmin.changelist_view。将表单添加到上下文并自定义更改列表模板以呈现此表单。提交表单应该产生正确的搜索GET请求。