2016-08-16 6 views
2

で2つのクエリセットに参加することは、私はすべてのユーザーのための賞の数と、すべてのユーザ(すなわちのために使用され数々の賞含むクエリセットを取得したいと、私は次のモデルにジャンゴ

class Award(models.Model): 
    user = models.ForeignKey(User) 


class AwardReceived(models.Model): 
    award = models.ForeignKey(award) 
    date = models.DateField() 
    units = models.IntegerField() 


class AwardUsed(models.Model): 
    award = models.ForeignKey(award) 
    date = models.DateField() 
    units = models.IntegerField() 

を持っていると仮定どちらも)。私は各計算のために1つのクエリを行うことを好む - 私は私のコードでそれを組み合わせたときにいくつかの予期しない結果があった。また、私のクエリのいくつかについては、クエリが複雑すぎるので、1つのクエリを実行することはできません - 私は8つのフィールドを計算しています。これはこれまで私がそれを解決した方法です:

def get_summary(query_date) 
    summary = (Award.objects.filter(awardreceived__date__lte=query_date)) 
        .annotate(awarded=Sum('awardissuedactivity__units_awarded'))) 

    awards_used = (Award.objects.filter(awardused__date__lte=query_date) 
         .annotate(used=Sum('awardused__date__lte__units'))) 

    award_used_dict = {} 
    for award in awards_used: 
     award_used_dict[award] = award.used 

    for award in summary: 
     award.used = award_used_dict.get(award, 0) 

    return summary 

辞書アプローチなしでこれを解決する方法が必要でしょうか?たとえば、次のようなものがあります:awards_used.get(award=award)しかし、これはループごとにdbルックアップを引き起こします。

また、他のいくつかのファンシーな方法でクエリセットに参加できますか?

これは単純な例であり、この例ではDB構造を改善することができますが、私は自分の質問を説明しようとしています。

+0

あなたの試験では、「exercised_awards_dict」とは何ですか? –

+0

申し訳ありませんが、コードからコピーしましたが、すべての変数名が変更されていませんでした。今すぐ固定 – Johan

答えて

5

SOLUTION 1

だけ

final_q = summary | awards_used 

が更新あなたの例では|

final_q = q1 | q2 

を使用して、クエリセットを連結しよう:

|計算された属性を使用した作品は、そう、私たちは

summary = Award.objects.filter(awardreceived__date__lte=query_date) 
awards_used = Award.objects.filter(awardused__date__lte=query_date) 
final_q = summary | awards_used 

final_q = final_q.annotate(used=Sum('awardused__date__lte__units')).annotate(awarded=Sum('awardissuedactivity__units_awarded')) 

SOLUTION 2

使用して私たちの特別な属性がありチェーン組み込み関数

from itertools import chain 
final_list = list(chain(summary, awards_used)) 

をマッピング最初にして、私たちのクエリセットを選択することができていませんこのアプローチの問題ですが、クエリーセットを取得しない場合は、インスタンスを含むリストを取得します。

+0

final_q [0] .usedを使用すると、属性エラーが発生します。これは、計算された値が|を使用するときに含まれていないかのようです。 – Johan

+0

@Johan私は私の答えを更新しました – levi

+0

すばらしいおかげで、私はそれを試してみましょう。リストを取得する気にしないでください – Johan