/ DjangoのORMワット日付に基づいた値のクエリ
-
21-09-2019 - |
質問
I値と日付フィールドを持つオブジェクトの束を持っています:
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の
編集ます:
ただ、ノートに、私の例では、わずか数日に及ぶことが、実際には、私はカップルの数十年をカバーする数百個のオブジェクトを持っているが...私は何をしようとしていることは、すべての方法合計を示す折れ線グラフを作成することです私のオブジェクトが時間をかけて成長してきました(非常に長い時間)
解決
この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)]
このことを回避するには、毎日のために別のクエリを実行します。
他のヒント
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を持っている場合、それはより多くの1以下だ場合には、、あなたはそれらの上でlen(OBJ)をチェックする必要があり、反復でしょう。
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の実行中の集計を行うには、この(これが最も神託の方法であることは確かではない)。
を行うことができます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]
EDITます:
:あなたが不足している日間のアカウントに必要な場合、私はdictの()構文を好むものの、@Glennメイナードの答えは、実際にはかなり良いです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]
所属していません StackOverflow