Django - limiting query results
Django querysets are lazy. That means a query will hit the database only when you specifically ask for the result.
So until you print or actually use the result of a query you can filter further with no database access.
As you can see below your code only executes one sql query to fetch only the last 10 items.
In [19]: import logging
In [20]: l = logging.getLogger('django.db.backends')
In [21]: l.setLevel(logging.DEBUG)
In [22]: l.addHandler(logging.StreamHandler())
In [23]: User.objects.all().order_by('-id')[:10]
(0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" ORDER BY "auth_user"."id" DESC LIMIT 10; args=()
Out[23]: [<User: hamdi>]
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.