0

Plone 使您可以使用日期范围过滤搜索结果。正常日期范围是通过仅使用最小日期设置的,因此范围介于今天和过去的某个日期之间。

我需要添加使用开始日期和结束日期设置日期范围的选项。

I was thinking on adding an extra option that, when selected, will show a couple of date pickers, but I don't know how to set the created.query:record:list:datevariable to use this 2 values.

我试过在query变量上传递一个列表,但后来我得到:

Error Value: Invalid DateTime "[DateTime('2000/07/14 00:00:00 GMT-3'), DateTime('2014/07/14 00:00:00 GMT-3')]"

以前有没有其他人发现过这样的要求?你是怎么解决的?这应该移植到核心吗?

4

2 回答 2

2

您可能希望为您的索引名称传递一个查询字典——带有一个范围参数。假设您的索引已“修改”并且您想要一个最小值和最大值范围,例如:

>>> from DateTime import DateTime
>>> from Products.CMFCore.utils import getToolByName
>>> catalog = getToolByName(site)
>>> startDT = DateTime(2010,12,1)
>>> endDT = DateTime(2013,12,1)
>>> query = {
...     'modified': {
...         query: (startDT, endDT),
...         range: 'min:max',
...         }
...     }
... 
>>> result = catalog.unrestrictedSearchResults(query)  # or .search()

此处记录了类似的内容:http: //docs.plone.org/develop/plone/searching_and_indexing/query.html#querying-by-date

于 2014-07-14T20:46:02.673 回答
1

我花了一些时间对此进行调查,并且有一个可行的解决方案。

首先我们需要了解 Zope 和ZPT是如何工作的;当您使用类似于created.query:record:list:date告诉 Zope 进行一些参数转换的内容命名表单元素时:

  • record,将变量转换为记录属性
  • list,将变量转换为 Python 列表
  • date,将字符串转换为 DateTime 对象

有关这方面的更多信息,您可以查看Advanced Zope Scripting

因此,参数会自动转换为 Python 中这样的字典记录:

'created': {'query': [DateTime('2014/07/09 00:00:00 GMT-3')], 'range': 'min'}

我的错误是假设我必须在一个请求变量上传递所有列表元素。

我在表单末尾添加的代码现在如下所示:

<input type="radio"
       id="query-date-range"
       name="created.query:record:list:date:ignore_empty"
       tal:attributes="value python:'';
                       checked python:checked=='' and 'checked' or '';"
       />
<label for="query-date-range" i18n:translate="time_range">Time range</label>
<input type="text"
       id="range-start"
       name="created.query:record:list:date:ignore_empty">
<input type="text"
       id="range-end"
       name="created.query:record:list:date:ignore_empty">
<script>
var today = new Date();
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
var start = yesterday.toLocaleDateString().slice(0, 10);
var end = today.toLocaleDateString().slice(0, 10);
$(document).ready(function() {
    $("#range-start").datepicker();
    $("#range-end").datepicker();
    $('#range-start').hide();
    $('#range-end').hide();
});

$('input:radio').change(function() {
    var option = $('input:radio:checked', '#searchform').val();
    if (option === '') {
        $('#range-start').val(start);
        $('#range-start').show();
        $('#range-end').val(end);
        $('#range-end').show();
        $('#range').val('min:max');
    }
    else {
        $('#range-start').val('');
        $('#range-start').hide();
        $('#range-end').val('');
        $('#range-end').hide();
        $('#range').val('min');
    };
});
</script>

请特别注意以下事项:

  • 开始日期和结束日期是与 jQueryUI 日期选择器小部件关联的输入元素。

  • created.query:record:list:date:ignore_empty两个输入元素的名称相同(

'created': {'query': [DateTime('2014/07/15 00:00:00 GMT-3'), DateTime('2014/07/16 00:00:00 GMT-3')], 'range': 'min:max'}
  • 我们设置了一个额外的参数转换器(ignore_empty),它只是避免将没有设置值的元素添加到列表中(我也将此转换器添加到其他输入元素)。

  • 当我们点击query-date-range元素时,我们必须初始化日期选择器;当我们单击任何其他元素时,我们需要清除这些值以避免将它们添加到列表中。

  • 我们还range根据@sdupton 之前提到的查询类型更改元素的值。

肯定可以增强代码的 JavaScript 部分;我的技能真的很有限。

于 2014-07-17T00:38:28.613 回答