Solución:
Los conjuntos de consultas de Django son perezosos. Eso significa que una consulta llegará a la base de datos solo cuando solicite específicamente el resultado.
Entonces, hasta que imprima o realmente use el resultado de una consulta, puede filtrar más sin acceso a la base de datos.
Como puede ver a continuación, su código solo ejecuta una consulta SQL para recuperar solo los últimos 10 elementos.
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>]
De hecho, creo que el LIMIT 10
se emitiría a la base de datos, por lo que la división no se produciría en Python sino en la base de datos.
Consulte limiting-querysets para obtener más información.
Parece que la solución de la pregunta ya no funciona con Django 1.7 y genera un error: “No se puede reordenar una consulta una vez que se ha tomado un segmento”.
De acuerdo con la documentación https://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysets forzar el parámetro “paso” de la sintaxis del segmento de Python evalúa la consulta. Funciona de esta manera:
Model.objects.all().order_by('-id')[:10:1]
Aún así, me pregunto si el límite se ejecuta en SQL o Python corta toda la matriz de resultados devuelta. No es bueno recuperar listas enormes en la memoria de la aplicación.