views:

1686

answers:

3

Essentially I need a count of each Entries Comments:

SELECT e.*, COUNT(c.id) as comments FROM blog_entry e LEFT JOIN blog_comment c ON e.id = c.entry_id GROUP BY e.id, e.name, e.name_slug, e.date_published, e.category, e.image, e.body, e.is_published, e.views, e.subscription_sent ORDER BY e.date_published DESC LIMIT 15;

But I don't know how to go about this using Django.

This is what I have so far, it works perfectly, except there's no comment count. Can someone point me in the correct direction for making joins like this using Django?

from project.blog.models import Entry, Comment

def index(request):
    latest_entry_list = Entry.objects.filter(is_published=True).order_by('-date_published')[:15]
    return render_to_response('blog/index.html', {'latest_entry_list': latest_entry_list)
+6  A: 

django 1.1 have support for aggregate queries, you can grab the last version via the svn trunk. The doc is already updated

http://docs.djangoproject.com/en/dev/topics/db/aggregation/

Tiago
So there's currently no other way to handle something like this for the exception of dropping into raw SQL?
Ty
I think that this is what you want:http://docs.djangoproject.com/en/dev/topics/db/aggregation/#generating-aggregates-for-each-item-in-a-querysetisn´t it?
Tiago
Yes, It's just a pain that I have to updrade to a development version. Thanks for your help.
Ty
If you really prefer to stick with 1.0 for now, you can use this method until you switch to 1.1: http://stackoverflow.com/questions/327807/django-equivalent-for-count-and-group-by#327987
Carl Meyer
+1  A: 

Without the aggregation branch you could do the following which returns a list of 2tuples:

  from project.blog.models import Entry, Comment

  def index(request):
    latest_entry_list = Entry.objects.filter(is_published=True).order_by('-date_published')[:15]
    latest_entry_list_comment_count = [(x, x.count()) for x in latest_entry_list]
    return render_to_response('blog/index.html', {
         'latest_entry_list': latest_entry_list,
)

Just use this in your templates:

{% for entry in latest_entry_list %}
    Entry: {{entry.0}}
    Comment count: {{entry.1}}
{% endif %}
andybak
+2  A: 

If you're not using trunk Django (and hence can't use the new aggregation stuff) you can achieve this with a subselect passed to the extra() QuerySet argument. The Django documentation for extra() uses what you're trying to achieve as an example (under the select heading) here.

Simon Willison