在 Django QuerySet 中指定限制和偏移量不起作用
Posted
技术标签:
【中文标题】在 Django QuerySet 中指定限制和偏移量不起作用【英文标题】:Specifying limit and offset in Django QuerySet wont work 【发布时间】:2014-07-25 08:09:53 【问题描述】:我使用的是 Django 1.6.5 并打开了 mysql 的通用查询日志,所以我可以看到 sql 命中 MySQL。 而且我注意到在 Django 的 QuerySet 中指定更大的限制不起作用:
>>> from blog.models import Author
>>> len(Author.objects.filter(pk__gt=0)[0:999])
>>> len(Author.objects.all()[0:999])
MySQL 的一般日志显示两个查询都有LIMIT 21
。
但是小于 21 的限制会起作用,例如len(Author.objects.all()[0:10])
将使用 LIMIT 10
创建一个 sql。
这是为什么呢?有什么需要配置的吗?
【问题讨论】:
那只表示数据库中有21个条目,注意slice不会报错。 【参考方案1】:Django 使用 Python 的数组切片语法实现 OFFSET
。如果要偏移前 10 个元素,然后显示接下来的 5 个元素,请使用它
MyModel.objects.all()[OFFSET:OFFSET+LIMIT]
例如,如果您想在偏移量 10 后检查 5 个作者,那么您的代码将如下所示:
Author.objects.all()[10:15]
您可以阅读更多关于它的信息here in the official Django doc
我也围绕这个概念写了一篇博客,you can here more here
【讨论】:
【参考方案2】:LIMIT
和 OFFSET
在 Django 中的工作方式与我们期望的不同。
例如。
如果我们必须从第 10 行开始读取接下来的 10 行,并且如果我们指定:
Author.objects.all()[10:10]
它将返回空记录列表。为了获取接下来的 10 行,我们必须将偏移量添加到限制中。
Author.objects.all()[10:10+10]
它会返回从第10行开始的下10行的记录列表。
【讨论】:
【参考方案3】:我确实可以工作,但 django 使用了迭代器。它不会一次加载所有对象。
【讨论】:
【参考方案4】:对于我使用和为我工作的偏移量和限制:)
MyModel.objects.all()[offset:limit]
例如:-
Post.objects.filter(Post_type=typeId)[1:1]
【讨论】:
我认为切片应该是[offset: offset + limit]
。
但事实并非如此@neuront 它的 [offset:limit]
把它想象成 [FROM:TO]
当我使用带有偏移量和限制的过滤器时,我得到这个错误 '>=' not supported between 'str' and 'int'【参考方案5】:
当您从 shell 进行查询时会发生这种情况 - 添加了 LIMIT
子句以阻止您的终端在调试时填满数千条记录:
您正在打印(或至少尝试打印) 查询集。为了避免人们不小心尝试检索和打印 百万个结果,我们(好吧,我)将其更改为仅检索和打印 如果有更多结果,则打印前 20 个结果并打印“remainder truncated”。 这是通过将查询限制为 21 个结果来实现的(如果有 21 个 结果有 20 多个,因此我们打印“截断”消息)。 这只发生在 repr() 中 - 即它仅用于诊断 印刷。没有普通用户代码会自动包含此限制,因此 您很高兴地创建了一个迭代超过一百万个结果的查询集。
(Source)
【讨论】:
我从来不知道。如果可以的话,我会投票 10 次!以上是关于在 Django QuerySet 中指定限制和偏移量不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何在 django 中指定索引类型? (btree 与哈希等)