Django: Applying Calculations To A Query Set
- by TheLizardKing
I have a QuerySet that I wish to pass to a generic view for pagination:
links = Link.objects.annotate(votes=Count('vote')).order_by('-created')[:300]
This is my "hot" page which lists my 300 latest submissions (10 pages of 30 links each). I want to now sort this QuerySet by an algorithm that HackerNews uses:
(p - 1) / (t + 2)^1.5
p = votes minus submitter's initial vote
t = age of submission in hours
Now because applying this algorithm over the entire database would be pretty costly I am content with just the last 300 submissions. My site is unlikely to be the next digg/reddit so while scalability is a plus it is required.
My question is now how do I iterate over my QuerySet and sort it by the above algorithm?
For more information, here are my applicable models:
class Link(models.Model):
category = models.ForeignKey(Category, blank=False, default=1)
user = models.ForeignKey(User)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
url = models.URLField(max_length=1024, unique=True, verify_exists=True)
name = models.CharField(max_length=512)
def __unicode__(self):
return u'%s (%s)' % (self.name, self.url)
class Vote(models.Model):
link = models.ForeignKey(Link)
user = models.ForeignKey(User)
created = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return u'%s vote for %s' % (self.user, self.link)
Notes:
I don't have "downvotes" so just the presence of a Vote row is an indicator of a vote or a particular link by a particular user.