87 votes

Django annote le compte avec un champ distinct

J'ai deux modèles définis grossièrement comme ceci :

class InformationUnit(models.Model):
    username = models.CharField(max_length=255)
    project = models.ForeignKey('Project')
    ...

class Project(models.Model):
    name = models.CharField(max_length=255)

Maintenant, dans une vue, je veux annoter tous les éléments suivants InformationUnit qui appartiennent à un projet, donc je fais ça :

p = Project.objects.all().annotate(Count('informationunit')

ce qui fonctionne très bien.

De plus, je veux savoir, dans chaque projet, combien de projets distincts username participent. C'est-à-dire, compter combien de personnes distinctes username sont présents dans le InformationUnit qui composent un projet. J'ai essayé ce qui suit, mais cela ne fait que compter le nombre de projets qui composent un projet. InformationUnit indépendamment de la username :

p = Project.objects.all().annotate(Count('informationunit__username')

Notez que username n'est pas un objet, c'est une chaîne de caractères. Existe-t-il un moyen propre de faire cela ou dois-je créer un code plus compliqué à base de boucles et de code spaghetti :P

Merci beaucoup !

180voto

spencer nelson Points 1306

Count peut prendre un distinct argument, comme ça :

p = Project.objects.all().annotate(Count('informationunit__username', 
                                         distinct=True))

Cela ne semble pas être documenté, mais vous pouvez le trouver dans la source de Count.

39voto

Mouscellaneous Points 625

Si vous voulez simplement compter les valeurs distinctes, vous pouvez utiliser les fonctions distinct() et count() :

count = Project.objects.values('informationunit__username').distinct().count()

14voto

ragsagar Points 742
Project.objects.all().annotate(Count('informationunit__username', 
                                     distinct=True))

6voto

WeizhongTu Points 1212

SQL SELECT field1, COUNT(DISTINCT(pk)) FROM project GROUP BY field1 ORDER BY NULL;

Jeu de requêtes

Project.objects.all().values(field1).annotate(count=Count('pk', distinct=True)).order_by()

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