【问题标题】:Django admin date range filterDjango 管理员日期范围过滤器
【发布时间】:2017-06-26 02:47:47
【问题描述】:

我正在尝试为 Django 管理员编写客户日期范围字段。这是我的过滤器,与docs 中提供的十年示例非常相似,但不适用于我。我究竟做错了什么?它只显示每个选择的所有记录。

class DaysSinceAdvertFilter(admin.SimpleListFilter):
    # Human-readable title which will be displayed in the
    # right admin sidebar just above the filter options.
    title = _('Days Since Advert')

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

    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 (
            ('0', _('Less than 7 days')),
            ('7', _('7-13 days')),
            ('14', _('14-20 days')),
            ('21', _('21-27 days')),
            ('28', _('28-34 days')),
            ('35', _('35+ days')),
        )

    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 to decide how to filter the queryset.
        today = datetime.date.today()
        if self.value() == '0':
            return queryset.filter(last_advert__gte=today - datetime.timedelta(days=6))
        if self.value() == '7':
            return queryset.filter(last_advert__gte=today - datetime.timedelta(days=13),
                                   last_advert__lte=today - datetime.timedelta(days=7))
        if self.value() == '14':
            return queryset.filter(last_advert__gte=today - datetime.timedelta(days=20),
                                   last_advert__lte=today - datetime.timedelta(days=14))
        if self.value() == '21':
            return queryset.filter(last_advert__gte=today - datetime.timedelta(days=27),
                                   last_advert__lte=today - datetime.timedelta(days=21))
        if self.value() == '28':
            return queryset.filter(last_advert__gte=today - datetime.timedelta(days=34),
                                   last_advert__lte=today - datetime.timedelta(days=28))
        if self.value() == '35':
            return queryset.filter(last_advert__lte=today - datetime.timedelta(days=35))

last_advert 是 models.DateField

【问题讨论】:

    标签: python django django-admin


    【解决方案1】:

    您可以简单地使用last_advert__range 为您的范围创建一个字典,与您在 lookups() 中创建的元组相同 像这样的东西

     no_of_routes_dict = {
        '7': [14, 20]}
    

    queryset()

    filt_no_of_routes=request.GET.get['para']
    `last_advert__range`= no_of_routes_dict[filt_no_of_routes]
    

    这可能会有所帮助

    class NumberOfRoutesFilter(SimpleListFilter):
    title = 'Date Range'
    parameter_name = 'date-range'
    date_dict = {
        '0': [0, 7],
        '7': [7, 13],
        '14': [14, 20],
        '21': [21, 27],
    
    }
    
    def lookups(self, request, model_admin):
        return [
           ('0', 'Less than 7 days'),
            ('7', '7-13 days'),
            ('14', '14-20 days'),
            ('21', '21-27 days')
        ]
    
    def queryset(self, request, queryset):
        filt_date = request.GET.get('date-range')
        if filt_date:
            return queryset.filter(
                last_advert__range=self.date_dict[filt_date]
            )
        return queryset
    

    【讨论】:

    • 我不明白。 last_advert 是一个日期,而不是一个数字,但大概我可以在您的查找中使用日期而不是数字,但是我如何在管理过滤器中实现它?