Python 基于日期和Django ORM查询值

Python 基于日期和Django ORM查询值,python,django,django-orm,Python,Django,Django Orm,我有一堆对象,它们有一个值和一个日期字段: obj1 = Obj(date='2009-8-20', value=10) obj2 = Obj(date='2009-8-21', value=15) obj3 = Obj(date='2009-8-23', value=8) 我要退回这个: [10, 15, 0, 8] 或者更好的是,在这一点上的总和: [10, 25, 25, 33] 我最好直接从数据库中获取这些数据,否则我可以使用forloop非常轻松地进行合计 我正在使用Django

我有一堆对象,它们有一个值和一个日期字段:

obj1 = Obj(date='2009-8-20', value=10)
obj2 = Obj(date='2009-8-21', value=15)
obj3 = Obj(date='2009-8-23', value=8)
我要退回这个:

[10, 15, 0, 8]
或者更好的是,在这一点上的总和:

[10, 25, 25, 33]
我最好直接从数据库中获取这些数据,否则我可以使用forloop非常轻松地进行合计

我正在使用Django的ORM和Postgres

编辑:

需要注意的是,我的示例只涵盖了几天,但实际上,我有数百个对象涵盖了几十年。。。我要做的是创建一个折线图,显示我所有对象的总和是如何随着时间的推移而增长的

result_list = []
for day in range(20,24):    
    result = Obj.objects.get(date=datetime(2009, 08, day))
    if result:
        result_list.append(result.value)
    else:
        result_list.append(0)
return result_list
如果每个日期有多个Obj,则需要检查lenobj,并在超过1的情况下对其进行迭代


如果您每个日期有多个Obj,您需要检查lenobj,并在超过1的情况下对其进行迭代。

这一个没有测试,因为设置Django表来测试有点太麻烦了:

from datetime import date, timedelta
# http://www.ianlewis.org/en/python-date-range-iterator
def datetimeRange(from_date, to_date=None):
    while to_date is None or from_date <= to_date:
        yield from_date
        from_date = from_date + timedelta(days = 1)

start = date(2009, 8, 20)
end = date(2009, 8, 23)
objects = Obj.objects.filter(date__gte=start)
objects = objects.filter(date__lte=end)

results = {}
for o in objects:
    results[o.date] = o.value

return [results.get(day, 0) for day in datetimeRange(start, end)]

这避免了每天运行单独的查询。

此查询未经测试,因为设置Django表进行测试有点麻烦:

from datetime import date, timedelta
# http://www.ianlewis.org/en/python-date-range-iterator
def datetimeRange(from_date, to_date=None):
    while to_date is None or from_date <= to_date:
        yield from_date
        from_date = from_date + timedelta(days = 1)

start = date(2009, 8, 20)
end = date(2009, 8, 23)
objects = Obj.objects.filter(date__gte=start)
objects = objects.filter(date__lte=end)

results = {}
for o in objects:
    results[o.date] = o.value

return [results.get(day, 0) for day in datetimeRange(start, end)]

这样可以避免每天运行单独的查询。

如果循环遍历Obj.objects.get 100次,则执行100次SQL查询。Obj.objects.filter将在一个SQL查询中返回结果,但您也可以选择所有模型字段。正确的方法是使用Obj.objects.values\u list,这将通过单个查询完成,并且只选择“values”字段

start_date = date(2009, 8, 20)
end_date = date(2009, 8, 23)

objects = Obj.objects.filter(date__range=(start_date,end_date))
# values_list and 'value' aren't related. 'value' should be whatever field you're querying
val_list = objects.values_list('value',flat=True)
# val_list = [10, 15, 8]
要进行val_列表的运行聚合,您可以这样做,但不确定这是最具python风格的方法

for i in xrange(len(val_list)):
    if i > 0:
        val_list[i] = val_list[i] + val_list[i-1]

# val_list = [10,25,33]
编辑:如果你需要解释缺失的天数,@Glenn Maynard的答案实际上相当不错,尽管我更喜欢dict语法:

objects = Obj.objects.filter(date__range=(start_date,end_date)).values('date','value')
val_dict = dict((obj['date'],obj['value']) for obj in objects)
# I'm stealing datetimeRange from @Glenn Maynard
val_list = [val_dict.get(day, 0) for day in datetimeRange(start_date, end_date)]
# val_list = [10,15,0,8]

如果对Obj.objects.get循环100次,则执行100次SQL查询。Obj.objects.filter将在一个SQL查询中返回结果,但您也可以选择所有模型字段。正确的方法是使用Obj.objects.values\u list,这将通过单个查询完成,并且只选择“values”字段

start_date = date(2009, 8, 20)
end_date = date(2009, 8, 23)

objects = Obj.objects.filter(date__range=(start_date,end_date))
# values_list and 'value' aren't related. 'value' should be whatever field you're querying
val_list = objects.values_list('value',flat=True)
# val_list = [10, 15, 8]
要进行val_列表的运行聚合,您可以这样做,但不确定这是最具python风格的方法

for i in xrange(len(val_list)):
    if i > 0:
        val_list[i] = val_list[i] + val_list[i-1]

# val_list = [10,25,33]
编辑:如果你需要解释缺失的天数,@Glenn Maynard的答案实际上相当不错,尽管我更喜欢dict语法:

objects = Obj.objects.filter(date__range=(start_date,end_date)).values('date','value')
val_dict = dict((obj['date'],obj['value']) for obj in objects)
# I'm stealing datetimeRange from @Glenn Maynard
val_list = [val_dict.get(day, 0) for day in datetimeRange(start_date, end_date)]
# val_list = [10,15,0,8]


数据库什么数据库?直到我们结束并在标记中看到您使用的是Django,因此可能是它的内置ORM-如果您使用的是不同的ORM,您应该指定!,这个问题很混乱,;在将来,请把这些信息放在主题中,或者放在前面。我在这里做了适当的编辑。哇,对不起。是的,我在使用django ORM,我也在使用PostgresCan,我们假设每个日期只有一个或零个对象?数据库?什么数据库?直到我们结束并在标记中看到您使用的是Django,因此可能是它的内置ORM-如果您使用的是不同的ORM,您应该指定!,这个问题很混乱,;在将来,请把这些信息放在主题中,或者放在前面。我在这里做了适当的编辑。哇,对不起。是的,我在使用django ORM,我也在使用PostgresCan我们假设每个日期只有一个或零个对象?django查询集是惰性计算的,因此实际上每天都要运行一个单独的查询。除了这里的查询集只在for循环开始时计算一次,所以这很好。每次调用o.value时,您都会访问数据库,因此每天都会访问数据库。不,当调用对象时,ORM会访问数据库,并为所有满足筛选条件的Obj对象选择所有字段日期、值等。大卫,您非常困惑。它不会针对每一个o.value命中数据库。它运行一个单独的查询,批量返回结果。Django queryset是惰性计算的,因此实际上每天都会运行一个单独的查询。除了这里的queryset在for循环开始时只计算一次,所以这很好。每次调用o.value时,您都会访问数据库,因此每天都会访问数据库。否,当调用objects.\uuuu iter\uuuuuuuuuuuu时,ORM将命中数据库,并为所有满足筛选条件的Obj对象选择所有字段日期、值等。大卫,你太糊涂了。它不会针对每一个o.value命中数据库。它运行一个查询,批量返回结果。此答案无法给出数据库中不存在的天数值。-1因为对我的解决方案提出错误声明,然后给出与我完全相同的解决方案,但不太清楚。当我写下此答案时,我不清楚DB是否会丢失日期。你是对的,如果DB缺少日期,那么你的解决方案就可以了。这个答案无法给出数据库中不存在的天数的值。-1因为对我的解决方案做出错误的声明,然后给出与我完全相同的解决方案,但不太清楚。当我写这篇文章时 我不清楚DB是否会错过日期。你是对的,如果数据库缺少日期,那么你的解决方案就可以了。