2

I'm trying to write a customer date range field for Django admin. This is my filter, which is very similar to the decade example provided in the docs but is not working for me. What am I doing wrong? It just shows all records for every selection.

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 is a models.DateField

1 Answer 1

1

You can use simply last_advert__range create a dict for the your ranges same as tuple you have created in lookups() Some thing like this

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

and in queryset()

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

This might help

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
1
  • 1
    I don't understand. last_advert is a date, not a number but presumably I can use dates instead of numbers in you lookup but how do I implement this in an admin filter?
    – HenryM
    Commented Feb 8, 2017 at 14:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.