Copy change_list.html template from here to your templates (name it for example custom_change_list.html).

Add next to block result_list

{% block result_list %}
        <div style="float: right">{{ range_form }} <button type="button" class="button" onclick="apply_range()">Apply</button></div>


Also you can append <script> section to {% block content %} that will put dates into date GET param:

      function apply_range() {
        var fy = document.getElementById('id_from_date_year').value;
        var fm = document.getElementById('id_from_date_month').value;
        var fd = document.getElementById('id_from_date_day').value;
        var ty = document.getElementById('id_to_date_year').value;
        var tm = document.getElementById('id_to_date_month').value;
        var td = document.getElementById('id_to_date_day').value;
        window.location.href = '/admin/someurl/?date__gte='+fy+'-'+fm+'-'+fd+'&date__lt=+ty+'-'+tm+'-'+td+';

This param will be mapped into iternal queryset for your model, so models will be filtered by field named date.

Add next to

class RangeForm(forms.Form):
    yrs = [( - i) for i in range(6)]

    from_date = forms.DateField(widget=SelectDateWidget(years=yrs))
    to_date = forms.DateField(widget=SelectDateWidget(years=yrs))

class Ma(admin.ModelAdmin):
    change_list_template = 'custom_change_list.html'

    def changelist_view(self, request, extra_context=None):
        extra_context = extra_context or {}

        if 'date__gte' in request.GET:
            from_date = request.GET['date__gte'].split('t')
            to_date = request.GET['date__lt'].split('t')
            initial = {
                'from_date':  datetime.datetime.strptime(from_date, '%Y-%m-%d').date(),
                'to_date': datetime.datetime.strptime(to_date, '%Y-%m-%d').date()
            initial = {
                'from_date': ( - timedelta(days=365*5)).date(),
        extra_context['range_form'] = RangeForm(initial=initial)
        return super(Ma, self).changelist_view(request, extra_context=extra_context)

Using non-model fields

If your model has no date field and you want to use it for some other case (aggregations, etc) then you should add date get param to admin.views.main.IGNORED_PARAMS.

In add:

from django.contrib.admin.views import main as views_main
views_main.IGNORED_PARAMS += ('date',)