6

(I'm new to python and django so please bear with me for a second. I apologise if this has been answered elsewhere and couldn't find it)

Let's say I have a Link model and through the django-voting application users can vote on link instances. How can I order those link instances according to their score, eg. display those with the higher score first.

I assume I could use the get_top manager of django-voting, but that would only give me the top scoring link instances and wouldn't take into consideration other parameters I would like to add (for example, those links that belong to a specific user or paging or whatever).

My guess would be to write a custom manager for my Link model where by I can filter a queryset according to each item's score. If I understand correctly that will require me to loop through each item, check its score, and then place it a list (or dictionary) which will then be sorted according to the score of each item. That wouldn't return a queryset but a dictionary with each item.

Am I missing something here?

edit:

Here's a stripped-down version of the Link model:

class Link(models.Model):
    user = models.ForeignKey('auth.User')
    category = models.ForeignKey(Category)  
    date = models.DateTimeField( auto_now_add=True, null=True, blank=True )
    is_deleted = models.BooleanField(default=False, blank=True)
    links = ValidLinkManager()
    objects = models.Manager()

and when a user votes I have this in my view:

Vote.objects.record_vote(link, user, vote)

where link is the Link instance, user is an instance of auth.User and vote is either 1, 0, or -1. The ValidLinkManager just filters out those links that have is_deleted set to True.

Nicolas R
  • 991
  • 2
  • 8
  • 17
  • Can you post some code, possibly what your Link model looks like...? – kafuchau May 17 '10 at 12:00
  • I'm not quite sure what you are trying to do here. Are you just trying to order the display of the votes? – Brant May 17 '10 at 13:36
  • No, I want to order a Link queryset according to the score/votes of each item. The goal is to display items that have the highest score first. – Nicolas R May 17 '10 at 13:48

2 Answers2

1

The get_top method in VoteManager isn't that complicated. Look at its code (in managers.py:122). You can easily create a version of it that accepts a filter as another parameter and applies it to the "objects" queryset after it creates it, in line 158 - this way you can add other filters like the ones you're missing.

Maybe you can also offer that as a patch back to the jonathan, and he'll put it in django-voting :)

Ofri Raviv
  • 24,375
  • 3
  • 55
  • 55
0

I chose to use a generic relation in my model:

votes = generic.GenericRelation(Vote)

and then to aggregate it:

my_model.objects.annotate(num_votes=Count('votes'))

In this case I am just counting the number of votes received by the objects, but you can switch Count with Avg to get an average.

Since this does not work with Django by default, I installed django-generic-aggregation.

Paolo Moretti
  • 54,162
  • 23
  • 101
  • 92
Bastian
  • 5,625
  • 10
  • 44
  • 68