2017-04-06 4 views
0

に().count使用するようにこれらは私が私の小さなプロジェクトタグのリストが私に与えられている右の時間DjangoのORM

class Tag(models.Model): 
    name = models.CharField(max_length=200) 

class Post(models.Model): 
    content = models.CharField(max_length=200) 
    tags = models.ManyToManyField(Tag) 
    location = models.PointField(null=True, blank=True) 

(最大3)を持っているモデルがあります。これらのタグのそれぞれが投稿に表示されるタグの回数を調べる必要があります。その後、私は次のクエリを使用して、すべてのポストデータをフェッチ私は

for tag in tags: 
     tag_data[tag] = Post.objects.filter(
      tags__name=tag, 
      location__distance_lte=(
       pnt, D(km=distance))).count() 

をやっているタグの数を取得するために

[「ハイテク」、「面白い」、「オタク」]言うことができます。

posts = Post.objects.filter(
      tags__name__in=tags, 
      location__distance_lte=(pnt, D(km=distance))) 

私はすでに機能の最後に投稿をループしています。

for post in posts: 
    #some logic 

私はそこにタグのデータがあることを知っています。カウントを見つけるために上記のような別々のデータクエリを行う必要はありません。しかし、私はforループ内のタグの数を見つけたいと思ったら、forループ内に1つ以上forループが必要です。

for post in posts: 
    #some logic 
    for tag in post.tags: 
     #some logic 

ここで私の質問がより効率的です。 .count()を使ってフェッチするか、ループのためにネストします。 DjangoのORMで

+0

'tag_data [em_id]'に 'em_id'とは何ですか? –

+0

それはタイプミスでした。 updated –

+0

私が理解しているように、特定の 'Post'でタグ付けされた' Tag'の数を数えたいと思っています。正しい?あるいは 'Post'''タグがいくつ使われたのかを数えたいのですか?あなたが数えたい実際のものは何ですか? –

答えて

2

お問い合わせに探している機能を追加し.annotate().aggregate()方法を使用していると呼ばれる集約何かがあります。 (Docs on Aggregation)。

はちょうどあなたの場合と同様に多対多の関係を通して、あなたは、このようなCountAvgSumを取得し、more.Thisも行うことができるように物事を行うことができる方法の例がたくさんあります。

There's even an exampleご使用のケースに非常に似ています。

たとえば、書籍のリストを取得している場合、各書籍に投稿された著者の数を知りたい場合があります。各書籍は著者と多対多の関係を持っています。 QuerySetの各ブックについてこの関係を要約したいと考えています。

はこれを行うだろうあなたに登場しているPostTagの量をカウントするには、次の

# Add any arguments you want to the filter() to narrow down the Tag query set. 
tags = Tags.objects.filter().annotate(Count('post_set')) 
# You access it as post_set__count 

EDIT:あなたは、あなたがに条件を追加したい供給コメントに基づいて

注釈とクエリを使用して、半径内にある投稿のみをカウントすることができます。これを行うには、Djangoが Conditional Expressionsと呼ぶものを使います。

条件式の助けを借りて、.annotate()に条件を追加することができます。

例:

tags = Tags.objects.filter().annotate(Count(
     Case(When(post_set__location="1", then=1), output_field=IntegerField()) 
)) 

あなたのケースでそれを使用するための適切な方法を見つけるために、ドキュメントをお読みください。 Conditional Expressions with Aggregationsが表示されます。

+0

私は理解しました。しかし、投稿にフィルタを適用する場所は混乱しています。あなたが見る通り、私は位置条件(* location__distance_lte =(pnt、D(km =距離)*)を満たす投稿だけが必要です。 –

+0

あなたは以前に場所フィールドを無視すべきだと書いたことがあります...しかし、正しく理解すれば、 'Tag'が存在する' Post'の数を数えたいと思いますが、半径の内側にある 'Post'を数えるだけです?だからあなたは 'Tag'カウントを合計したくないので、' Post'位置で制限したいのですか? –

+0

はい。誤って指摘して申し訳ありません。私がIgnoreと言ったとき、私はフィルターフィールドとみなしていました。私はタグの数を欲しいと郵便番号 –

関連する問題