Answers:
Django查询集很懒。这意味着查询仅在您明确要求结果时才会命中数据库。
因此,在您打印或实际使用查询结果之前,无需进行数据库访问就可以进一步过滤。
如您在下面看到的,您的代码仅执行一个sql查询以仅获取最后10个项目。
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>]
实际上,我认为LIMIT 10
它将被发布到数据库,因此切片不会在Python中发生,而是在数据库中发生。
有关更多信息,请参见限制查询集。
看起来问题中的解决方案不再适用于Django 1.7,并引发错误:“一旦获取切片,就无法对查询重新排序”
根据文档https://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysets强制使用Python slice语法的“ step”参数评估查询。它是这样工作的:
Model.objects.all().order_by('-id')[:10:1]
仍然我想知道限制是在SQL还是Python中执行的,是对返回的整个结果数组进行切片。将巨大的列表检索到应用程序内存是没有好处的。
作为对其他有用答案的补充和观察,值得注意的是[:10]
,切片实际上 将返回列表的前10个元素,而不是后10 个元素。
要获得最后的10个,您应该[-10:]
改为这样做(请参阅此处)。这将帮助您避免使用order_by('-id')
与-
反转元素。
Product.objects.filter(~Q(price=0))[-5:]
导致我同样的错误:“不支持负索引。”