Home > OS >  How to mix multiple querysets into one and re order them by time created?
How to mix multiple querysets into one and re order them by time created?

Time:10-22

I am learning Django and still a beginner. For practising, i am trying to make a demo social media website. In my project, users can create groups, then they can post and comment there. In the home page, i am trying to add a section like 'recent activities' where a user can see recent activities in that website like "John created a group 'Javascript', Tim posted a comment in 'Python', Sarah posted in 'CSS'" Now i have made some queries like: groups = Group.objects.all().order_by('-created')[0:5] posts = Post.objects.all().order_by('-created')[0:5] comments = Comment.objects.all().order_by('-created')[0:5]

I want to mix them all in a single queryset. Then order them all by the time they were created. I know it's a silly question and i have been stuck here since morning. Can you help me and show me the process please?

CodePudding user response:

You can chain these together and order by the created field with:

from operator import attrgetter

groups = Group.objects.order_by('-created')[:5]
posts = Post.objects.order_by('-created')[:5]
comments = Comment.objects.order_by('-created')[:5]
all_items = sorted(
    [*groups, *posts, *comments],
    key=attrgetter('created'),
    reversed=True
)

Now all_items is a hetrogenous list with different types of objects. This will thus make the rendering process a bit more complicated since a comment probably has different fields than a Post for example.

CodePudding user response:

You can also use chain function from itertools module to combine the querysets and then sort them in reverse order using the created field as key.

from itertools import chain

groups = Group.objects.all()[0:5]
posts = Post.objects.all()[0:5]
comments = Comment.objects.all()[0:5]

queryset = sorted(
    chain(groups, posts, comments),
    key=lambda instance: instance.created,
    reverse=True
)
  • Related