在 Django 管理中按自定义日期范围过滤

发布于 2024-08-10 11:11:53 字数 248 浏览 4 评论 0原文

Django 管理站点可以按自定义日期范围选择条目,即使用两个 DateFieldsAdminDateWidget 吗?我知道有 date_hierarchylist_filter 属性,但是当有大量数据库条目并且您只需要按精确的 < 过滤项目时,它们似乎不太有用。 code>date__gte 和 date__lte 查询。

Can Django admin site select entries by a custom date range, i.e. using two DateFields with AdminDateWidget? I know that there are date_hierarchy and list_filter properties, but they don't seem very useful when there are a lot of DB entries and you just need to filter items by exact date__gte and date__lte query.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

时光沙漏 2024-08-17 11:11:54

在 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 发送了一个补丁,所以,请尽快检查一下。

In django 1.4, you can user list_filter. try:

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

This will give some built-in ranges, but it will work if you put the date range in url, like:

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

If you need a date picker (like jquery), then you need to extend DateFieldListFilter. I sent a patch to django-admin-filtrate, so, check there soon.

雨后彩虹 2024-08-17 11:11:54

注意:我在 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 年 5 月、6 月或 7 月的所有条形对象。

然后,如果您覆盖 admin/change_list.html 模板文件,您可以添加开始和结束日期的小部件,导航到所需的网址。


Daniel 致敬回答另一个SO问题,它教我如何使用查询集过滤器参数作为GET参数。

Note: I wrote this answer in 2009, when the required functionality was not available in Django as a public API. For Django 1.4+, see the other answers.

This functionality isn't provided as far as I'm aware, but you can build it yourself.

Firstly, you can filter items using date__gte and date__lte as GET arguments in the url.

For example

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

will display all bar objects with dates in May, June or July 2009.

Then if you override the admin/change_list.html template file, you can add widgets for start and end dates, which navigate to the required url.


Hat tip to Daniel's answer to another SO question, which taught me about using queryset filter parameters as GET arguments.

蘸点软妹酱 2024-08-17 11:11:54

现在可以使用标准 Django API 轻松实现自定义管理过滤器。在文档日,您现在可以在 list_filter 中添加:

继承自 django.contrib.admin.SimpleListFilter 的类,您需要为其提供 title 和parameter_name 属性并覆盖查找和查询集方法

并且它们继续到 演示(滚动到第二个项目符号)。我自己使用它来添加过滤器,其与对象的底层关系不是通过模型属性,而是通过它们的方法的结果,这是传统过滤器不提供的。

It's now possible to easily implement Custom Admin filters using standard Django APIs. The docs day that in the list_filter, you can now add:

a class inheriting from django.contrib.admin.SimpleListFilter, which you need to provide the title and parameter_name attributes to and override the lookups and queryset methods

And they go ahead to demo (scroll to the second bullet). I've used this myself to add filters whose underlying relation to the objects isn't via model attributes, but results of methods on them, something which the traditional filters don't offer.

随遇而安 2024-08-17 11:11:54

我最终实现了这样的内容,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

I ended up implementing it something like this, 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 %}

The date column being filtered is trade_date.

冷了相思 2024-08-17 11:11:54

DateRangeFilter() 类位于 https://github.com/runekaagaard/django-admin-滤液就是这样做的:)

The DateRangeFilter() class found at https://github.com/runekaagaard/django-admin-filtrate does just that :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文