On May 27, 2011, at 9:58 AM, bax...@gretschpages.com wrote:

> I have a "watch" model that lets users keep an eye on various things
> through a generic relation:
> 
> class Watch(models.Model):
>    subscriber = models.ForeignKey(User, verbose_name="Subscriber")
>    content_type = models.ForeignKey(ContentType)
>    content_object = generic.GenericForeignKey()
>    object_id = models.IntegerField('object ID')
>    created = models.DateTimeField(auto_now_add=True)
> 
> 
> What I'm trying to do is get the most-watched objects.
> I saw James Bennett's snippet from 2007 (http://djangosnippets.org/
> snippets/108/) which looks like it would work (subbing my Watch model
> for comments), but I'm wondering if there's a better way to do it with
> newer versions of django, possibly through annotate or aggregate?
> 

If you were to do something like this:

from django.models import count
most = Watch.objects.values('content_type', 
'object_id').annotate(Count('object_id')).order_by('-object_id__count')

[
        {'object_id__count': 15, 'object_id': 1, 'content_type': 10},
        {'object_id__count': 2, 'object_id': 1, 'content_type': 5},
        ...
]

# this isn't efficient, but you get the idea
# you need to resolve the content types and object id's into models 
from django.contrib.contenttypes.models import ContentType
for object in most:
        foo = ContentType.objects.get(id= 
object['content_type']).get_object_for_this_type(object['object_id'])


You can also see
https://github.com/coleifer/django-generic-aggregation

This will get you close but I think it only if you want to annotate the count 
on a single content type at once.

Jason Culverhouse
http://www.mischievous.org

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to