Efficient Django query filter first n records

Viewed 833

I'm trying to filter for the first (or last) n Message objects which match a certain filter. Right now I need to filter for all matches then slice.

def get(self, request, chat_id, n):
    last_n_messages = Message.objects.filter(chat=chat_id).order_by('-id')[:n]
    last_n_sorted = reversed(last_n_messages)
    serializer = MessageSerializer(last_n_sorted, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)

This is clearly not efficient. Is there a way to get the first (or last) n items without exhaustively loading every match?

2 Answers

I found the answer myself. Basically the [:n] puts a SQL "LIMIT" in the query which makes the query itself NOT exhaustive. So it's fine in terms of efficiency.

Link for similar answer below. https://stackoverflow.com/a/6574137/4775212

If the limit is known, it can also be using range.

Message.objects.filter(chat__range=[chat_id, chat_id+n]).order_by('-id')
Related