Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Seems like you could overload the <code>save</code> of the <code>Vote</code> class and have it update the corresponding <code>Link</code> object. Something like this should work well:</p> <pre><code>from datetime import datetime, timedelta class Link(models.Model): category = models.ForeignKey(Category) user = models.ForeignKey(User) created = models.DateTimeField(auto_now_add = True) modified = models.DateTimeField(auto_now = True) fame = models.PositiveIntegerField(default = 1) title = models.CharField(max_length = 256) url = models.URLField(max_length = 2048) #a field to keep the most recently calculated popularity popularity = models.FloatField(default = None) def CalculatePopularity(self): """ Add a shorcut to make life easier ... this is used by the overloaded save() method and can be used in a management function to do a mass-update periodically """ ts = datetime.now()-self.created th = ts.seconds/60/60 self.popularity = (self.user_set.count()-1)/((th+2)**1.5) def save(self, *args, **kwargs): """ Modify the save function to calculate the popularity """ self.CalculatePopularity() super(Link, self).save(*args, **kwargs) def __unicode__(self): return self.title class Vote(models.Model): link = models.ForeignKey(Link) user = models.ForeignKey(User) created = models.DateTimeField(auto_now_add = True) modified = models.DateTimeField(auto_now = True) karma_delta = models.SmallIntegerField() def save(self, *args, **kwargs): """ Modify the save function to calculate the popularity of the Link object """ self.link.CalculatePopularity() super(Vote, self).save(*args, **kwargs) def __unicode__(self): return str(self.karma_delta) </code></pre> <p>This way every time you call a link_o.save() or vote_o.save() it will re-calculate the popularity. You have to be a little careful because when you call <code>Link.objects.all().update('updating something')</code> then it won't call our overloaded <code>save()</code> function. So when I use this sort of thing I create a management command which updates all of the objects so they're not too out of date. Something like this will work wonderfully:</p> <pre><code>from itertools import imap imap(lambda x:x.CalculatePopularity(), Link.objects.all().select_related().iterator()) </code></pre> <p>This way it will only load a single Link object into memory at once ... so if you have a giant database it won't cause a memory error.</p> <p>Now to do your ranking all you have to do is:</p> <pre><code>Link.objects.all().order_by('-popularity') </code></pre> <p>It will be super-fast since all of you Link items have already calculated the popularity.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload