20

I have a list of IDs for objects that I need to grab, then I have to sort them by their timestamp. Here's how I was going to do it:

For i in object_ids:
  instance = Model.objects.get(id = i)
  # Append instance to list of instances 

#sort the instances list

But there are two things that bother me:

  • Is there no way to grab a collection of entries by a list of their IDs - without having to loop?
  • Can I append arbitrary objects to the QuerySet just based on their IDs ?

Thanks,

Goro
  • 9,919
  • 22
  • 74
  • 108

2 Answers2

33

This can be done using such a code:

objects = Model.objects.filter(id__in=object_ids).order_by('-timestamp')

the order_by can be positive or negative timestamp, depending how you want it sorted.

kender
  • 85,663
  • 26
  • 103
  • 145
  • 6
    What's the nicest way to get the objects returned in the same order as the object_ids list? The OPs code? – Chris Sep 26 '15 at 21:30
  • 2
    I would probably fetch the data from the database with only one call (such as above) and then make the sorting in your code. Should be faster then querying the database N times. Especially with a large N. – kender Sep 28 '15 at 08:28
  • @kender @Chris Do we have any solution for `in the same order as the object_ids list` rather than sorting after fetching? – Dipak Mar 03 '16 at 05:10
  • @Dipak I retrieved them as in @kendor's answer, put them in a `dict` `id->object`, then iterated `object_ids` for the key. I didn't test the performance as it wasn't critical. – Chris Mar 04 '16 at 15:17
  • @Dipak I found a brilliant answer that returns a queryset here: https://stackoverflow.com/a/37648265/1526703 – Anupam Jan 20 '18 at 13:11
10

Try the following:

result = Model.objects.filter(id__in=object_ids)

This returns all Model objects that have their id in the given list of object_ids. This way, you also don't need to append additional models to the resulting QuerySet.

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180