Фильтрация по пользовательскому диапазону дат в Django admin

14 Dmitry Gladkov [2009-11-03 18:54:00]

Может ли сайт администратора Django выбирать записи в пользовательском диапазоне дат, т.е. используя два DateFields с AdminDateWidget? Я знаю, что есть свойства date_hierarchy и list_filter, но они не кажутся очень полезными, когда есть много записей в базе данных, и вам просто нужно фильтровать элементы точным запросом date__gte и date__lte.

date filter django django-admin


6 ответов


20 Решение Alasdair [2009-11-04 00:28:00]

Примечание. Я написал этот ответ в 2009 году, когда требуемая функциональность не была доступна в Django как открытый API. Для Django 1.4+ см. Другие ответы.

Эта функция не предоставляется, насколько мне известно, но вы можете ее самостоятельно создать.

Во-первых, вы можете фильтровать элементы с помощью date__gte и date__lte в качестве аргументов GET в URL-адресе.

Например

/admin/myapp/bar/?date__gte=2009-5-1&date__lt=2009-8-1

отобразит все объекты бара с датами в мае, июне или июле 2009 года.

Затем, если вы переопределите файл шаблона admin/change_list.html, вы можете добавить виджеты для дат начала и окончания, которые переходят к требуемому URL-адресу,


Совет о шляпе Даниэль ответит на другой вопрос SO, который научил меня использовать параметры фильтра запросов в качестве аргументов GET.


32 bsm [2012-05-14 23:19:00]

В django 1.4 вы можете использовать list_filter. попробуйте:

from django.contrib.admin import DateFieldListFilter
class PersonAdmin(ModelAdmin):
    list_filter = (
        ('date_field_name', DateFieldListFilter),
    )

Это даст некоторые встроенные диапазоны, но будет работать, если вы установите диапазон дат в URL-адресе, например:

?date__gte=2009-5-1&date__lt=2009-8-1

Если вам нужен выбор даты (например, jquery), вам нужно расширить DateFieldListFilter. Я отправил патч на django-admin-filtrate, так что скоро проверьте его.


5 Rune Kaagaard [2011-07-13 12:54:00]

Класс DateRangeFilter(), найденный в https://github.com/runekaagaard/django-admin-filtrate, делает именно это:)


4 fossilet [2016-06-16 07:28:00]

Вы можете использовать эту современную версию: https://github.com/tzulberti/django-datefilterspec. Ниже снимок экрана


4 nemesisfixx [2013-02-22 11:15:00]

Теперь можно легко реализовать пользовательские фильтры с помощью стандартных API Django. День документа, который в list_filter теперь можно добавить:

класс, наследующий от django.contrib.admin.SimpleListFilter, который вам необходимо предоставить атрибуты title и parameter_name для переопределения методов поиска и запросов

И они перейдут к demo (прокрутите до второй пули). Я сам использовал это для добавления фильтров, базовое отношение которых к объектам не связано с атрибутами модели, но результаты методов на них, то, что традиционные фильтры не предлагают.


3 dan-klasson [2012-04-18 18:14:00]

В итоге я реализовал что-то вроде этого:

 # admin.py
 class FooAdmin(MyModelAdmin):

     def changelist_view(self, request, extra_context=None):

         extra_context = extra_context or {}
         try:
             extra_context['trade_date_gte'] = request.GET['date__gte']
         except:
             pass

         try:
             extra_context['trade_date_lte'] = request.GET['date__lte']
         except:
             pass

     return super(FileNoteAdmin, self).changelist_view(request, extra_context)  


# change_list.html

{% extends "admin/admin/change_list.html" %}
{% load i18n admin_static admin_list %}
{% load url from future %}
{% load admin_urls %}


{% block filters %}

{% if cl.has_filters %}
  <div id="changelist-filter">
    <h2>{% trans 'Filter' %} </h2>

<h3>By trade date</h3>

<link href="/media/css/ui-lightness/jquery-ui-1.8.19.custom.css" rel="stylesheet" type="text/css"/>
<script src="/media/js/jquery/jquery-min.js"></script>
<script src="/media/js/jquery/jquery-ui-1.8.19.custom.min.js"></script>

<script>

    $(function() {
        $( "#trade_date_gte" ).datepicker({ dateFormat: 'yy-mm-dd'{% if trade_date_gte %}, defaultDate: '{{ trade_date_gte }}'{% endif %} }); 
        $( "#trade_date_lte" ).datepicker({ dateFormat: 'yy-mm-dd'{% if trade_date_lte %}, defaultDate: '{{ trade_date_lte }}'{% endif %} });
    });

function applyDateFilters() {

    qs = location.search;

    if (qs.charAt(0) == '?') qs = qs.substring(1);

    var qsComponents = qs.split(/[&;]/g);

    new_qs = [];
    for (var index = 0; index < qsComponents.length; index ++){

        var keyValuePair = qsComponents[index].split('=');
        var key          = keyValuePair[0];
        var value        = keyValuePair[1];

        if(key == 'trade_date__gte' || key == 'trade_date__lte' || key == '') {
            continue;
        } else {
            new_qs[index] = key + '=' + value;
        }
    }

    if($( "#trade_date_gte" ).val() != '') {
        new_qs[new_qs.length] = 'trade_date__gte=' + $( "#trade_date_gte" ).val();
    }
    if($( "#trade_date_lte" ).val() != '') {
        new_qs[new_qs.length] = 'trade_date__lte=' + $( "#trade_date_lte" ).val();
    }

    window.location = '?' + new_qs.join("&");
}
</script>

<p>
From: <br /><input type="text" id="trade_date_gte" value="{{ trade_date_gte|default:'' }}" size="10"><br />
To: <br /><input type="text" id="trade_date_lte" value="{{ trade_date_lte|default:'' }}" size="10">
</p>

<ul>
    <li><a href="#" onclick="javascript:applyDateFilters();">Apply date filters</a></li>
</ul>

    {% for spec in cl.filter_specs %}{% admin_list_filter cl spec %}{% endfor %}
  </div>
{% endif %}
{% endblock %}

Фильтрация столбца даты - "trade_date".