[django] Django - limiting query results

I want to take the last 10 instances of a model and have this code:

 Model.objects.all().order_by('-id')[:10]

Is it true that firstly pick up all instances, and then take only 10 last ones? Is there any more effective method?

This question is related to django

The answer is


Yes. If you want to fetch a limited subset of objects, you can with the below code:

Example:

obj=emp.objects.all()[0:10]

The beginning 0 is optional, so

obj=emp.objects.all()[:10]

The above code returns the first 10 instances.


Actually I think the LIMIT 10 would be issued to the database so slicing would not occur in Python but in the database.

See limiting-querysets for more information.


Looks like the solution in the question doesn't work with Django 1.7 anymore and raises an error: "Cannot reorder a query once a slice has been taken"

According to the documentation https://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysets forcing the “step” parameter of Python slice syntax evaluates the Query. It works this way:

Model.objects.all().order_by('-id')[:10:1]

Still I wonder if the limit is executed in SQL or Python slices the whole result array returned. There is no good to retrieve huge lists to application memory.


As an addition and observation to the other useful answers, it's worth noticing that actually doing [:10] as slicing will return the first 10 elements of the list, not the last 10...

To get the last 10 you should do [-10:] instead (see here). This will help you avoid using order_by('-id') with the - to reverse the elements.