2016-04-14 11 views
1

投票のアプリについては、商品評価(「Product_r」)(product_codeにグループ化されている)ごとに、product_code,Count()、製品レーティング> 3が必要です。Djangoのフィルタクエリで注釈付きの割合を計算する方法は?

私は最後の注釈式で計算を取り除くことができると思っていましたが、そうではないようです。

下記の試みは動作しません
q = Product_r.objects.all()\ 
    .annotate(product_code=F('fk_product__product_code'))\ 
    .values('product_code')\ 
    .annotate(count=Count('id'))\ 
    .annotate(proportion=Count(score__gt=3)/count) 

のどちらかが(countが定義されていないと文句を言い、そしてまたそれが全体クエリ、割合を計算していないだけで、その後の注釈部分をフィルタリング):

q = Product_r.objects.all()\ 
    .annotate(product_code=F('fk_product__product_code'))\ 
    .values('product_code')\ 
    .annotate(count=Count('id'))\ 
    .filter(score__gt=3)\ 
    .annotate(proportion=Count('id')/count) 

クエリを2回コーディングせずに(このうちの1つをscore__gt=3でフィルタリング)、2つのcountの値を分割する方法はありますか? This blog postは、この種の処理に未加工のSQLを使用しています。私がここで私の場合はそれを避けることができれば幸いです。

+0

「Count( 'id')/ F( 'count') 'を試してください。私はそれが動作するかどうかはわかりませんが、定義されていないカウントについてのエラーを停止します。 – Alasdair

+0

あなたは正しくありがとう、それはエラーを停止しました。クエリは依然として正しい出力を生成しません。フィルタはクエリ全体に適用され、すべての比率が「Count(すべて)/ Count(すべて)」すなわち1に等しくなります。 – Escher

答えて

0

これを実際に使用するには、私が使用したソリューションの簡略化されたバージョンがあります。テーブルが大きくなるにつれて、おそらくクエリの範囲を減らし、N個以上のレコードをフェッチすることができなくなるでしょう。それが誰かにとって有益だと思っています。

#http://stackoverflow.com/a/3422287/3790954 
#INNER JOIN two lists of dictionaries based on a common dictionary key 
def merge_lists(l1, l2, key): 
    merged = {} #will be a dict of dicts, with the primary key being the value to join on 
    for item in l1+l2: 
     if item[key] in merged: 
      merged[item[key]].update(item) 
     else: 
      merged[item[key]] = item 
    return [v for (k, v) in merged.items()] 

@login_required 
def tabulate_results(request): 
    first_list = Model1.objects.all().values_list('id', 'something', 'something_else') 
    second_list = Model2.objects.all().values_list('id', 'other_stuff') 
    #perform some sort of list comprehension here to get l1 and l2 
    #with the values you're interested in, then merge. 
    merged_list = merge_lists(l1, l2, 'id') 
    return render(request, "template.html", {"my_data": merged_list} 

はその後template.htmlに集計およびJavaScript(クライアント上に計算作業の一部をプッシュ)でソートします。

関連する問題