web-dev-qa-db-ja.com

Django adminのカスタム日付範囲によるフィルタリング

Django管理サイトはカスタムの日付範囲でエントリを選択できますか?つまり、2つのDateFieldsAdminDateWidgetを使用できますか?date_hierarchyプロパティとlist_filterプロパティがあることは知っていますが、 DBエントリが多数あり、正確なdate__gteおよびdate__lteクエリでアイテムをフィルタリングする必要がある場合は、あまり役に立たないようです。

22
Dmitry Gladkov

注:この回答は、必要な機能がパブリックAPIとしてDjangoで利用できなかった2009年に作成しました。 Django 1.4+については、他の回答を参照してください。

この機能は私が知る限り提供されていませんが、自分で作成することができます。

まず、URLのGET引数としてdate__gtedate__lteを使用してアイテムをフィルタリングできます。

例えば

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

2009年5月、6月、または7月の日付のすべてのバーオブジェクトが表示されます。

次に、 admin/change_list.html テンプレートファイルをオーバーライドすると、開始日と終了日のウィジェットを追加して、必要なURLに移動できます。


別のSO質問に対する Danielの回答 のヒント。これは、クエリセットフィルターパラメーターをGET引数として使用する方法を教えてくれました。

23
Alasdair

Django 1.4では、ユーザー list_filter 。try:

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にパッチを送信したので、すぐに確認してください。

39
bsm

この最新のものを使用できます: https://github.com/silentsokolov/Django-admin-rangefilter . Below is a screenshot

13
Fish Monitor

標準のDjango APIを使用してカスタム管理フィルターを簡単に実装できるようになりました。ドキュメントの日はlist_filter、次を追加できます:

django.contrib.admin.SimpleListFilterから継承するクラス。これには、title属性とparameter_name属性を指定し、ルックアップメソッドとクエリセットメソッドをオーバーライドする必要があります。

そして、彼らは デモ (2番目の箇条書きまでスクロール)に進みます。私はこれを自分で使用して、オブジェクトとの基本的な関係がモデル属性ではなく、それらのメソッドの結果であるフィルターを追加しました。これは、従来のフィルターでは提供されないものです。

8
nemesisfixx

https://github.com/runekaagaard/Django-admin-filtrate にあるDateRangeFilter()クラスはまさにそれを行います:)

5
Rune Kaagaard

私はそれを次のように実装することになりました、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

4
dan-klasson