bigmike7801
bigmike7801

Reputation: 3970

How to do a proper groupby query in django

I have a table that holds multiple tracking id's in it. What I'm trying to do is group all tracking id's and get a count for them.

This is what the SQL query would look like:

SELECT tracking_id, COUNT( * ) 
FROM tracking
GROUP BY tracking_id

I think I've found the correct method of doing this in django however I'm missing something and am currently getting the error Exception Value: 'dict' object has no attribute 'tracking_id'

Here's what my view looks like:

def stats(request):

    users = Tracking.objects.values('tracking_id').annotate(dcount=Count('tracking_id'))

    stats = []
    for user in users:
        stats.append((user.tracking_id, user.dcount))

    return render_to_response('tracking/stats.html', { 'stats': stats, })

Any help would be appreciated!

Upvotes: 0

Views: 355

Answers (2)

kgr
kgr

Reputation: 9948

How about (partially inspired by @second's answer):

users = Tracking.objects.values( 'tracking_id' ).annotate(dcount=Count('tracking_id'))

and then

for user in users:
    stats.append((user[ 'tracking_id' ], user[ 'dcount' ]))    

?

Upvotes: 2

second
second

Reputation: 28637

for times like this, I would recommend trying out your code in a shell

./manage.py shell opens a python shell with your project code in the system path

>>> from myapp.models import Tracking
>>> from django.db.models import Count
>>> Tracking.objects.values('tracking_id').annotate(dcount=Count('tracking_id'))

[{'tracking_id': 53, 'dcount': 12}, {'tracking_id': 1, 'dcount': 32}, ...]

this lets you see the format of the returned data and get you on your way

alternatively, you can add a pdb (python debugger) statement in your view code, (assuming runserver is serving your code), and load the page. when the pdb statement is reached, your server will stop and drop you into a debugger shell, right in the context of your view

def view(request):
    [...]
    import pdb; pdb.set_trace  # or even better, pip install ipdb and use instead

    return "foo"

Upvotes: 0

Related Questions