I am trying to build a Reddit or Hackernews-style community section for my website. Upvotes and downvotes are already implemented as well as date and time posted. The Post model has a method that returns a score for a particular post calculated based on upvotes, downvotes, and time posted. So far so good.
Now I don’t want to have to sort all my posts every single time a user loads a page. I think the solution to this (please correct me if I’m wrong) is to run a script every few minutes that sorts all the posts by score and saves them. Then when a user tries to load the front page the view will return the first 20 posts in the list of sorted posts, if someone loads the second page the view will return the next 20 items in the list and so on.
My naive approach was to have a model that looked something like this:
class SortedPosts(models.Model):
sortedPosts = models.ListField
And then a script to run every minute that looked like this:
from myproject.models import Post, SortedPosts
posts = Post.objects.all()
SortedPosts.sortedPosts = sorted(posts, key = lambda Post: Post.getScore())
SortedPosts.sortedPosts.save()
But alas, there is no such thing as a ListField (at least in vanilla Django.) When I search on SO, the only solution I’ve found is to serialize the list and store it in a TextField. That feels wrong. Is it?
The fact that there is no ListField in Django makes me suspect that the way I’ve set out to do this is incorrect in a more fundamental way. What would the correct way to do this be?
Actually in your particular situation the serialization/deserialization procedure
you imagine, might take even more time than sorting the posts with each request.
1000 objects are ridiculesly few , for a postgresql/mysql database.
Do nothing. If the need arises, use redis.
Either you need a caching mechanism or you don’t. In your case seems overkill.
UPDATE:
all django fields take the optional parameter “db_index”. If you set it to
Trueit willbuild an index on it.
Then I suppose you want to do something like
Post.objects.order_by('-rank')The “-” signifies
descendingorder. Remove it and you haveascendingorder.