web-dev-qa-db-ja.com

djangoでクエリセット内のオブジェクトの数を取得する

データベース内のオブジェクトの数のフィールドを追加するにはどうすればよいですか。私は次のモデルを持っています:

class Item(models.Model):
    name = models.CharField()

class Contest(models.Model);
    name = models.CharField()

class Votes(models.Model):
    user = models.ForeignKey(User)
    item = models.ForeignKey(Item)
    contest = models.ForeignKey(Contest)
    comment = models.TextField()

ContestAの投票を見つけるには、自分のビューで次のクエリを使用しています

current_vote = Item.objects.filter(votes__contest=contestA)

これは、すべての投票を個別に含むクエリセットを返しますが、各アイテムの投票数を取得したいのですが、どのようにそれを行うことができますか?ありがとう

46
thesteve

特定のアイテムの投票数を取得するには、次を使用します。

vote_count = Item.objects.filter(votes__contest=contestA).count()

特定のコンテストで投票の分布を分析したい場合は、次のようにします。

contest = Contest.objects.get(pk=contest_id)
votes   = contest.votes_set.select_related()

vote_counts = {}

for vote in votes:
  if not vote_counts.has_key(vote.item.id):
    vote_counts[vote.item.id] = {
      'item': vote.item,
      'count': 0
    }

  vote_counts[vote.item.id]['count'] += 1

これにより、アイテムを投票数にマップする辞書が作成されます。これを行う唯一の方法ではありませんが、データベースへのヒットはかなり少ないため、非常に迅速に実行されます。

83
Gary Chambers

これを行う別の方法は、 Aggregation を使用することです。単一のクエリを使用して、同様の結果を達成できるはずです。このような:

Item.objects.values("contest").annotate(Count("id"))

この特定のクエリはテストしませんでしたが、コンテストの各値のアイテム数を辞書として出力するはずです。

10
salomonvh