1

値と日付フィールドを持つオブジェクトがたくさんあります。

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 を使用しています

編集:

私の例は数日しかカバーしていませんが、実際には、数十年をカバーする何百ものオブジェクトがあります...私がやろうとしているのは、すべてのオブジェクトの合計が時間の経過とともに成長しました(非常に長い時間)

4

3 に答える 3

4

これはテストされていません。テストする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)]

これにより、毎日個別のクエリを実行する必要がなくなります。

于 2009-09-03T05:25:55.457 に答える
0
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 がある場合は、len(obj) をチェックし、複数の場合はそれらを反復処理する必要があります。

于 2009-09-03T04:48:36.593 に答える
0

Obj.objects.get を 100 回ループすると、100 回の SQL クエリが実行されます。Obj.objects.filter は 1 つの SQL クエリで結果を返しますが、すべてのモデル フィールドも選択します。これを行う正しい方法は、単一のクエリでこれを行う Obj.objects.values_list を使用し、「値」フィールドのみを選択することです。

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_list の実行中の集計を行うには、これを行うことができます (これが最も Pythonic な方法であるかどうかはわかりません)。

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]
于 2009-09-03T08:51:19.900 に答える