Django QuerySet: additional field for counting value's occurence


Django QuerySet: additional field for counting value's occurence



I have a QuerySet object with 100 items, for each of them I need to know how many times a particular contract_number occurs in the contract_number field.


QuerySet


contract_number


contract_number



Example of expected output:


[{'contract_number': 123, 'contract_count': 2}, {'contract_number': 456, 'contract_count': 1} ...]



This means that value 123 occurs 2 times for the whole contract_number field.


contract_number



Important thing: I cannot reduce the amount of items, so grouping won't work here.



The SQL equivalent for this would be an additional field contract_count as below:


contract_count


SELECT *,
(SELECT count(contract_number) FROM table where t.contract_number = contract_number) as contract_count
FROM table as t



The question is how to do it with a Python object. After some research, I have found out that for more complex queries the Queryset extra method should be used. Below is one of my tries, but the result is not what I have expected


queryset = Tracker.objects.extra(
select={
'contract_count': '''
SELECT COUNT(*)
FROM table
WHERE contract_number = %s
'''
},select_params=(F('contract_number'),),)



My models.py:


models.py


class Tracker(models.Model):
contract_number = models.IntegerField()



EDIT:
The solution to my problem was Subquery()




1 Answer
1



You can use annotation like this:


from django.db.models import Count
Tracker.objects.values('contract_number').annotate(contract_count=Count('contract_number')).order_by()





interesting, however instead of expected output, I am getting value: 1 for each item. For sure, there are contracts which are duplicated
– Supergator
Jul 3 at 9:42






@Supergator I suppose this is because of default ordering. Try to add order_by() as in my update. See detail here: docs.djangoproject.com/en/2.0/topics/db/aggregation/…
– neverwalkaloner
Jul 3 at 9:46


order_by()





Thanks, that's true, I had some ordering before in my query. Now, I am getting good counting values, the problem is that, it has reduced amount of items in the output - I have to keep original amount if items.
– Supergator
Jul 3 at 10:15





you have any idea, how to get counting values without reducing amount of items?
– Supergator
Jul 4 at 8:04






that's exactly what I needed, thanks a lot for your support
– Supergator
Jul 4 at 11:50






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

api-platform.com Unable to generate an IRI for the item of type

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?