2010-12-31 19 views
2

各リストの項目数をリストしたいと思います。各リストのクエリではなく、1つのクエリでどのようにこの数値を見つけることができますか?Django:クエリの最適化

ここ

が私の現在のテンプレートコードの簡易版である:List.objects.filter(ユーザー=ユーザー)

とNUM_ITEMSが一覧モデルのプロパティです:として

{% for list in lists %} 
<li> 
{{ listname }}: 
{% with list.num_items as item_count %} 
{{ item_count }} item{{ item_count|pluralize }} 
{% endwith %} 
</li> 
{% endfor %} 

リストが渡されます:

def _get_num_items(self): 
    return self.item_set.filter(archived=False).count() 
num_items = property(_get_num_items) 

これは、nがリストの数ですSELECT COUNT(*) FROM "my_app_item" WHERE...をn回、照会します。ここで単一のクエリを作成することは可能ですか?

+0

http://docs.djangoproject.com/en/dev/topics/db/aggregation/ –

+0

Ignacio氏は、あなたが指している「グループ化された集約」をどのように取得するかを尋ねていますが、話すことはありません。 –

+0

@Lakshman:あなたがそれを読んでいない場合にのみ。 –

答えて

1

あなたのビューでこれを行い、代わりに辞書を送信する必要があります。

Model.objects.values_list('item').annotate(Count('num_items')) 

これは、あなたが投稿した1、として(またはに相当)と同じSQLを生成します。

1

以下では、Listのフィールド、Itemのフィールド、項目の数、リスト単位のフィルタリングに関するすべての制約を考慮に入れました。唯一の2クエリ、リストを取得するための1、のために他を行います

from django.db.models import Count 
lists = list(List.objects.filter(user=user)) 
items=Item.objects.values(list).filter(archived=False,list__in=lists).annotate(count=Count("id")) 
#you will get a list of dicts of the form [{'count':2,'list':5},...] where 5 is the id of the list 
#now, you can match you list with you item counts in python 
list_items_count_dict={} 
for item in items: 
    list_items_count_dict[item['list']]=item['count'] 
for list in lists : 
    list.item_count = list_items_count_dict.get(list.id) 

私が見ソリューションは、あなたが値を()(http://docs.djangoproject.com/en/dev/topics/db/aggregation/#valuesここでは、この程度のDjangoドキュメントがある)を使用することができることです項目数を計算する。その後、次の2つのループ(それはおそらくリスト内包でワンライナーを置換することができる)を持つことになりますが、唯一のリストのために興味があります。

をその後、あなたのテンプレートで、あなたが使用することができます

{{list.item_count}} 

もっとエレガントなオプションがあるかもしれませんが、それは私が今見つけたものです。また、カスタムSQLを使用してクエリの数を1つに減らすこともできます。

免責事項:このコードはテストしていませんが、同様のモデルで同様のコードをテストしました。 listはPython言語のキーワードの1つなので、問題が発生する可能性があります。