以下行产生现有数据点的列表:

datapoint_list = organisation.datapoint_set.filter(timestamp__gte=startDate, timestamp__lte=endDate)


我想以JSON格式return的日期从startDatelastDate,对于这些日期没有现有的数据点。

如何才能做到这一点?

我最好的主意是:

class Missing(generics.ListAPIView)
    ...
    queryset = organisation.datapoint_set.filter(timestamp__gte=startDate, timestamp__lte=endDate)

    Loop over the datesdelta
        Loop over the datapoints
            If datapoint.timestamp == datedelta.timestamp then
                Push timestamp to object
                Continue
            End if
        End loop
    End loop
    Return object


但是我还没有成功实现日期循环。也许还有更简单的方法可以做到这一点?

编辑:

datedelta是根据查询参数确定的,默认情况下应在上周寻找缺失的数据点:

    days = int(self.request.query_params.get('days', 7))
    startDate = datetime.today() - timedelta(days)
    endDate = datetime.today()


查询集包含:

<DataPoint: Value: 123, Timestamp: 2015-12-15>
<DataPoint: Value: 123, Timestamp: 2015-12-11>
<DataPoint: Value: 123, Timestamp: 2015-12-10>
<DataPoint: Value: 123, Timestamp: 2015-12-09>
<DataPoint: Value: 123, Timestamp: 2015-12-08>


JSON输出应类似于

[
    'date': '2015-12-16',
    'date': '2015-12-14',
    'date': '2015-12-13',
    'date': '2015-12-12',
    'date': '2015-11-07'
}


我的问题是如何从该查询集获得该输出。

最佳答案

set()学习使用它,您将统治世界!首先,根据您向您展示的示例,您仅对日期稍作修改即可查询日期,因此可以提高查询效率:

queryset = organisation.datapoint_set.filter(timestamp__gte=startDate, timestamp__lte=endDate).values_list('timestamp', flat=True)


完成后,将如下所示:

queryset = [datetime(2015,12,15), datetime(2015,12,11), datetime(2015,12,10), datetime(2015,12,9), datetime(2015,12,8)]


现在,我们生成所需的值:

>>> set([endDate - timedelta(x) for x in xrange(days)])
set([datetime.date(2015, 12, 14), datetime.date(2015, 12, 16), datetime.date(2015, 12, 15), datetime.date(2015, 12, 12), datetime.date(2015, 12, 13), datetime.date(2015, 12, 10), datetime.date(2015, 12, 11)])


完美,我们(减去它们)-

>>> set([endDate - timedelta(x) for x in xrange(days)]) - set(queryset)
set([datetime.date(2015, 12, 14), datetime.date(2015, 12, 16), datetime.date(2015, 12, 15), datetime.date(2015, 12, 12), datetime.date(2015, 12, 13), datetime.date(2015, 12, 10), datetime.date(2015, 12, 11)])


让一切变得漂亮:

import datetime
days = 10
# a bit of a hack to get the current date without any time stuff.
endDate = datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time())
queryset = [datetime.datetime(2015,12,15), datetime.datetime(2015,12,11), datetime.datetime(2015,12,10), datetime.datetime(2015,12,9), datetime.datetime(2015,12,8)]
date_ranges = set([endDate - datetime.timedelta(x) for x in xrange(days)])
output = sorted(list(date_ranges - set(queryset)))
print([x.strftime('%Y-%m-%d') for x in output])


输出为:

['2015-12-07', '2015-12-12', '2015-12-13', '2015-12-14', '2015-12-16']


如果您将时间戳记作为date对象使用,则更加简单:

import datetime
days = 10
endDate = datetime.date.today()
queryset = [datetime.date(2015,12,15), datetime.date(2015,12,11), datetime.date(2015,12,10), datetime.date(2015,12,9), datetime.date(2015,12,8)]
date_ranges = set([endDate - datetime.timedelta(x) for x in xrange(days)])
output = sorted(list(date_ranges - set(queryset)))
print([x.strftime('%Y-%m-%d') for x in output])

10-07 19:12
查看更多