2017-12-11 4 views
2

私は似たような質問をいくつか見つけましたが、大部分は日付が付けられているか、あまりにも冗長すぎて参考になりません。2つ(またはそれ以上の)フィールドの合計でDjangoクエリーセットを注文する

私はこのようなモデルがあります:

class Breakfast(models.Model): 
    count_eggs = models.IntegerField() 
    count_bacon = models.IntegerField() 
    had_toast = models.BooleanField() 

を今、RESTfulなAPIを構築するには、私がモデルに恒久的にこれを格納することなく、count_eggs + count_baconの合計により、朝食のオブジェクトをソートする機能を必要としています。

Breakfast.objects.extra(
    select={'total_food':'count_eggs + count_bacon'}, 
    order_by=('total_food',) 
) 

これは、多くの、しかしDjango docs appear to dissuade this solutionのために働くようだ:

現在、人気の質問の多くは、このような何かを示唆しています。ですから、1.10+の世界では、このタイプのフィルタをDjangoの2つ(またはそれ以上)のフィールドの合計で行うにはどうすればよいでしょうか

+0

'order_by'に追加した方が簡単かもしれませんが、もっと良い答えがあると思います。 – cwallenpoole

答えて

1

Latrovas回答に若干の修正があり、彼のクエリは、それが不要なんSUMとGROUP_BYを働くだろうが。

次のように、より直感的なクエリは次のようになります。

Breakfast.objects.all().\ 
      annotate(total_food=F('count_eggs ') + F('count_bacon') 
      ).order_by('total_food') 

私はさらに一歩進み、クエリが舞台裏でどのように機能するか、あなたを説明したいと思います:

我々は注釈を付けたとき、私たちは」本質的には、SQL文のSELECT文に列を追加します。したがって、2つのフィールドの追加を実行するには、SELECT (eggs + bacon) as foodのようなselectステートメントが必要です。

これはと同じです。正確にはです。裏にはannotateがあります。

ハードコードされた値を使用する代わりに、データベース内に格納されている項目、つまりeggsbaconなどの列名を使用する必要があります。

そして、これはと正確にはとなります。F()という表現があります。

2つの全く異なるものを実行するので、2つを簡単に組み合わせて、両方を一緒に使用して、本当に強力なものにすることができます。

+1

優れた答え。私はもともと@ Latrovaの答えを受け入れましたが、このコード+説明のより簡潔な性質のため、これが受け入れられます。 – rob

+2

ニース、私も学んだ:)良い仕事 – Latrova

+1

ありがとう。私は助けになることができてうれしいです。私は長年にわたってどのように動作しているかを実際に理解することなく、注釈とより豪華なdjangoのものを使用しました。だから私は他の人に私の発見を説明するために最善を尽くしてきた^ _^ 答えを謝って申し訳ありません@Latrova hehe :) – oxalorg

4

注釈を使用する必要があります。お使いの場合に、これを試してください:

from django.db.models import F, Sum 

Breakfast.objects.all().\ 
      annotate(total_food=Sum(
       F('count_eggs ') + F('count_bacon')) 
      ).\ 
      order_by('total_food') 
関連する問題