开发者

Django: query latest posts from different categories

class Post(models.Model):
    title = ...
    category = models.ForeignKey(Category)
    date = .......

class Category(models.Model):
    title = ....

On the main page i want to display 5 posts with latest dates, but all posts must be from different categories. There is 50 categoriese, 开发者_C百科for example. Is it possible?


from django.db.models import Max

categories = Category.objects.annotate(most_recent=Max(post__date)).order_by('-most_recent')[:5]

posts = list()
for category in categories:
  posts.append(category.post_set.latest())

That annotates the categories with the date of the most recent post as the value of most_recent, which you can then order by to get the 5 most recent categories.

Then, just loop through the categories and pull out the latest post for each. Done.


Okay, let's try this again..

catsused = {}
posts = {}
postindex = 0
posts.add(Post.objects.order_by('date')[postindex])
catsused.add(Post.objects.order_by('date')[postindex].category

for each in range(1,5):
    postindex = postindex + 1
    post = Post.objects.order_by('date')[postindex] 
    while post.category in catsused:
        postindex = postindex + 1
        post = Post.objects.order_by('date')[postindex] 
    posts.add(post)
    catsused.add(post.category)

posts ## Now contains your posts

That seems like horrible code to me, but I suppose something close to that will do the job. You'll wanna add some code to handle "postindex" going over the number of posts there are in the system too.


You bet it's possible.

Randomly select 5 categories

Grab the most recent post for each category

Perhaps something like:

randposts = {} #list for most recent posts of 5 randomly selected categories
for randomcat in Category.objects.order_by('?')[5:]:
    randposts.add(Post.objects.filter(category = randomcat).order_by('date')[0])

This may help: https://docs.djangoproject.com/en/dev/ref/models/querysets/


Using order_by and distinct:

Post.objects.all().order_by('category', 'date').distinct('category')

Then for performance adding index together on category and date fields.

But i think real production way is to use Redis to cache and update an id's list of latest posts of categories.


Cleaned up version of Doc's code:

catsused = {}
posts = {}

for post in Post.objects.order_by('date'):
    if post.category not in catsused:
        posts.add(post)
        catsused.add(post.category)
        if len(catsused) == 5:
            break
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜