Django 从给定特定顺序的特定项目开始切片

Django 从给定特定顺序的特定项目开始切片,django,django-models,Django,Django Models,我正在尝试在Django上实现基于光标的分页。我从中学到了基本的知识 我知道我需要一个指向我所在位置的光标。前后。(如果我知道“count”,我将能够通过计算before+count=after来决定before或after),但我不知道如何使用Django获得它们。我想做的应该是这样的: posts = Post.objects.order_by('-created_date')[after:after+count] starting_date = Post.objects.filter(s

我正在尝试在Django上实现基于光标的分页。我从中学到了基本的知识

我知道我需要一个指向我所在位置的光标。前后。(如果我知道“count”,我将能够通过计算before+count=after来决定before或after),但我不知道如何使用Django获得它们。我想做的应该是这样的:

posts = Post.objects.order_by('-created_date')[after:after+count]
starting_date = Post.objects.filter(slug=slug).values('created_date')
later_posts = Post.objects.filter(created_date__lte=Subquery(starting_date[:1]))\
                          .order_by('-created_date')
但我不知道如何获取特定项的after索引,在本例中,它是一个游标。我只能在Python级别上考虑它

post = Post.objects.get(slug=slug)
queryset = Post.objects.order_by('-created_date')
after = list(queryset).index(post)
result = queryset[after:after+count]
这样,我必须从整个模型中查询所有对象。我认为这并不理想,但我既不知道如何执行查询以从特定项获取索引,也不知道如何从特定项获取切片


我只知道一个帖子的鼻涕虫。我的客户端没有主键。数据集从不按slug排序,但slug是唯一的键。

您可以获取创建日期早于特定slug的所有帖子,如下所示:

posts = Post.objects.order_by('-created_date')[after:after+count]
starting_date = Post.objects.filter(slug=slug).values('created_date')
later_posts = Post.objects.filter(created_date__lte=Subquery(starting_date[:1]))\
                          .order_by('-created_date')
现在,您可以对最后一个查询进行切片,以仅获取
计数
项:

later_posts[:count]
后者仍然是一个查询集,因此对数据库的实际查询不会涉及获取所有项。只需确保在
created\u date
slug
上为表编制索引,以提高效率

如果您从上一页(该页的最后一篇文章)中获得
slug
的值,则需要将其从新页中删除:

later_posts.exclude(slug=slug)[:count]

Django提供了几个类,可以帮助您管理分页数据,也就是说,使用“上一页/下一页”链接将数据拆分到多个页面上。这些类位于django/core/paginator.py中


您至少应该看看它是如何工作的,如果它不是您所需要的,是否可以修改。

谢谢您的评论!!这肯定比我最初想的要好。但是,考虑到人们通常向下滚动而不是向上滚动以刷新,过滤器将主要由最新版本创建。那么queryset的大小将是巨大的,它还假设created_date字段总是唯一的。。。这是最好的解决方案吗?我知道这比我上面写的要好…不,没有假设
created\u date
是唯一的,唯一的假设是
slug
是唯一的,因为我使用slug作为第一个条目。当你切片queryset
later_posts
,例如
later_posts[:20]
,你会创建一个新的queryset,因此你永远不会获取整个条目集。我已经更新了答案,以获取特定条目之前的帖子。您的“after”命名让我感到困惑。那么您的意思是当“code”later\u posts=Post.objects.filter(created\u date\u lte=Subquery(starting\u date[:1])\.order\u by('-created\u date')被执行时,它不会获取整个created\u date\u lte=Subquery(starting\u date[:1])??但是当后面的文章[:20]完成时,它就开始实际获取数据了?我很困惑,读吧。否,即使执行了
qs=later\u posts[:20]
,数据库中也不会计算任何内容。只有在实际循环项目以呈现它们时,才会实际计算查询集。查询集是懒惰的。我只是查看了一下,它似乎需要我查询整个对象,如示例所示。contact\u list=Contacts.objects.all()我试图避免这样查询所有对象。@初学者否,上面示例中的
contact\u list
是一个查询集,不会执行。如果在数据库上定义分页器并获取特定页面,则对数据库执行的实际查询是分页查询,而不是原始查询。但是:“如果使用的查询集包含大量项目,在某些数据库上请求高页码可能会很慢,因为生成的限制/偏移量查询需要计算偏移量记录的数量,而随着页码的增加,这需要更长的时间。“所以这取决于你的桌子有多大。哦,我明白了。我得多看看。这张桌子将非常大。我正在考虑使用大整数作为主键!