I have two models defined loosely like this:
class InformationUnit(models.Model): username = models.CharField(max_length=255) project = models.ForeignKey('Project') ... class Project(models.Model): name = models.CharField(max_length=255) Now, in a view, I want to annotate all the InformationUnits that belong to a project, so I do this:
p = Project.objects.all().annotate(Count('informationunit') which works just ok.
Furthermore, I want to know, in each project, how many distinct usernames participate. That is, count how many distinct usernames are there in the InformationUnits that compose one project. I have tried the following, but it simply counts the number of InformationUnit, regardless of the username:
p = Project.objects.all().annotate(Count('informationunit__username') Note that username is not an object, it is a string. Is there a clean way to do this or should I create a more complicated code based on loops and spaghetti code :P
Thanks a lot!
distinct() Returns a new QuerySet that uses SELECT DISTINCT in its SQL query. This eliminates duplicate rows from the query results. By default, a QuerySet will not eliminate duplicate rows.
We can use a distinct() query method at the end or in between queryset and with other regular Django query methods like all(), values(), etc…
Unlike aggregate() , annotate() is not a terminal clause. The output of the annotate() clause is a QuerySet ; this QuerySet can be modified using any other QuerySet operation, including filter() , order_by() , or even additional calls to annotate() .
Definition of the all() manager method: all() Returns a copy of the current QuerySet (or QuerySet subclass). This can be useful in situations where you might want to pass in either a model manager or a QuerySet and do further filtering on the result.
Count can take a distinct argument, like so:
p = Project.objects.all().annotate(Count('informationunit__username', distinct=True)) This doesn't seem to be documented, but you can find it in the source for Count.
If you just want to count the distinct values, you can use the distinct() and count() functions:
count = Project.objects.values('informationunit__username').distinct().count()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With