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 InformationUnit
s 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 username
s participate. That is, count how many distinct username
s are there in the InformationUnit
s 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