80 votes

Obtenir le nombre d'objets dans un queryset en django

Comment ajouter un champ pour le nombre d'objets dans une base de données. J'ai les modèles suivants :

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()

Pour trouver les votes pour le concours A, j'utilise la requête suivante dans ma vue

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

Cela renvoie un queryset avec tous les votes individuellement, mais je veux obtenir le nombre de votes pour chaque élément, quelqu'un sait-il comment je peux le faire ?

150voto

Gary Chambers Points 6465

Pour obtenir le nombre de votes pour un élément spécifique, vous devez utiliser :

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

Si vous souhaitiez connaître la répartition des votes dans un concours particulier, je ferais quelque chose comme ce qui suit :

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

Cela créera un dictionnaire qui associera les éléments au nombre de votes. Ce n'est pas la seule façon de procéder, mais cette méthode est assez peu gourmande en données, et s'exécute donc assez rapidement.

21voto

salomonvh Points 71

Une autre façon de procéder serait d'utiliser Agrégation . Vous devriez pouvoir obtenir un résultat similaire en utilisant une seule requête. Comme ceci :

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

Je n'ai pas testé cette requête spécifique, mais elle devrait permettre d'obtenir un décompte des éléments pour chaque valeur des concours sous la forme d'un dictionnaire.

1 votes

Je ne sais toujours pas où j'en suis. Si vous annotez un queryset, vous comptez le nombre d'identifiants appartenant à chaque objet, qui est évidemment 1. En quoi cela est-il utile ?

0 votes

Oui, si vous comptiez contest sur le modèle Contest, ce serait le cas. Toutefois, dans le cas présent, nous agrégeons les données sur le modèle du Item qui organisent des concours uniques.

0 votes

Que se passe-t-il si le nombre de deux objets est identique et que nous devons les trier en fonction d'une autre condition. Comment faire alors ?

0voto

sifar96 Points 1

Utiliser un nom apparenté pour compter les votes pour un concours spécifique

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, related_name="contest_votes")
    comment = models.TextField()

>>> comments = Contest.objects.get(id=contest_id).contest_votes.count()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X