5

I'm using the object_list generic view to quickly list a set of Articles. Each Article has comments attached to it. The query uses an annotation to Count() the number of comments and then order_by() that annotated number.

'queryset': Article.objects.annotate(comment_count=Count('comments')).order_by('-comment_count'),

The comments are part of the django.contrib.comments framework and are attached to the model via a Generic Relationship. I've added an explicit reverse lookup to my Article model:

class Article(models.Models):
   ...
   comments = generic.GenericRelation(Comment, content_type_field='content_type', object_id_field='object_pk')

The problem is, this counts "inactive" comments; ones that have is_public=False or is_removed=True. How can I exclude any inactive comments from being counted?

Soviut
  • 88,194
  • 49
  • 192
  • 260

1 Answers1

2

The documentation for aggregations explains how to do this. You need to use a filter clause, making sure you put it after the annotate clause:

Article.objects.annotate(comment_count=Count('comments')).filter(
     comment__is_public=True, comment__is_removed=False
).order_by('-comment_count')
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • wouldn't that filter articles based on whether or not they have public/removed comments? – Jiaaro Dec 03 '09 at 17:10
  • It seems to have worked but I'm going to do some investigating to make sure what Jim said isn't happening. – Soviut Dec 03 '09 at 17:49
  • One side effect I did notice is that it ONLY returns articles that have comments, those without are excluded. – Soviut Dec 04 '09 at 05:27