2009-11-03 113 views
14

Can Django管理站點可以通過自定義日期範圍選擇條目,即使用兩個DateFieldsAdminDateWidget?我知道有date_hierarchylist_filter屬性,但是當有很多數據庫條目時,它們似乎不是很有用,而您只需要按照確切的date__gtedate__lte查詢過濾項目。在Django中通過自定義日期範圍進行過濾admin

回答

20

注意:我在2009年編寫了這個答案,當時所需的功能在Django中不可用作爲公共API。對於Django 1.4+,請參閱其他答案。

據我所知,沒有提供此功能,但您可以自己構建它。

首先,您可以使用date__gtedate__lte作爲URL中的GET參數過濾項目。

例如

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

將顯示在五月,六月或七月日期所有酒吧對象2009

然後,如果你覆蓋admin/change_list.html模板文件,你可以添加開始和結束日期控件,導航到所需的網址。


帽尖到Daniel's answer到另一個SO問題,其教我使用查詢集的濾波器參數如GET參數。

+0

非常感謝,非常有用的功能。 – 2009-11-04 16:52:52

5

https://github.com/runekaagaard/django-admin-filtrate發現DateRangeFilter()類就是這樣做的:)

+0

似乎不適用於Django 1.4 – 2012-03-04 14:52:06

+0

未在1.4測試,所以可能不會。我認爲1.4中有一個新的管理過濾器api會動搖事情。 – 2012-03-05 08:41:58

3

我最終實現它是這樣的:

# 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」。

+0

現在我最終還是使用了你的過濾器(稍微定製了) - 在django-admin-filtered方面還沒有什麼。仍然缺少1.4支持 – kosta5 2013-02-27 19:07:12

32

在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-filtered發了一個補丁,所以請儘快查看。

+1

它將與django grappeli管理員一起工作嗎? – andi 2015-01-13 16:11:49

+0

@andi它應該工作。 – maciek 2016-09-13 10:19:46

5

現在可以使用標準的Django API輕鬆實現自定義管理過濾器。該文檔的一天,在list_filter,現在您可以添加:

一個類從django.contrib.admin.SimpleListFilter,您需要提供標題和PARAMETER_NAME屬性和覆蓋查詢和查詢集方法

繼承

然後他們繼續到demo(滾動到第二個項目符號)。我自己用這個來添加過濾器,這些過濾器與對象的底層關係不是通過模型屬性,而是它們的方法結果,這是傳統過濾器不提供的。

+1

爲什麼投票? – nemesisfixx 2015-08-05 13:06:41

+0

的確,非常有幫助,tx – ptim 2017-07-15 08:21:57