Django 如何从过滤有序的查询集中获取上一个和下一个对象?

Django 如何从过滤有序的查询集中获取上一个和下一个对象?,django,django-models,django-queryset,Django,Django Models,Django Queryset,我有一个基于模型对象的页面,我希望有到上一页和下一页的链接。我不喜欢当前的解决方案,因为它需要评估整个查询集(以获取id列表),然后再进行两个get查询。当然有什么方法可以一次性完成 def get_prev_and_next_page(current_page): ids = list(Page.objects.values_list("id", flat=True)) current_idx = ids.index(current_page.id) prev_page

我有一个基于模型对象的页面,我希望有到上一页和下一页的链接。我不喜欢当前的解决方案,因为它需要评估整个查询集(以获取
id
列表),然后再进行两个
get
查询。当然有什么方法可以一次性完成

def get_prev_and_next_page(current_page):
    ids = list(Page.objects.values_list("id", flat=True))
    current_idx = ids.index(current_page.id)
    prev_page = Page.objects.get(id=ids[current_idx-1])
    try:
        next_page = Page.objects.get(id=ids[current_idx+1])
    except IndexError:
        next_page = Page.objects.get(id=ids[0])
    return (prev_page, next_page)

排序顺序是在模型中定义的,因此不必在这里进行处理,但请注意,您不能假设ID是连续的。

听起来像是分页器设置为阈值1时会做得很好

# Full query set...
pages = Page.objects.filter(column=somevalue)
p = Paginator(pages, 1)

# Where next page would be something like...
if p.has_next():
     p.page(p.number+1)

而且。

我对Python和Django还不熟悉,所以我的代码可能不是最优的,但请检查以下内容:

def get_prev_and_next_items(target, items):
    ''' To get previous and next objects from QuerySet '''
    found = False
    prev = None
    next = None
    for item in items:
        if found:
            next = item
            break
        if item.id == target.id:
            found = True
            continue
        prev = item
    return (prev, next)
鉴于此:

def organisation(request, organisation_id):
    organisation = Organisation.objects.get(id=organisation_id)
    ...
    prev, next = get_prev_and_next_items(organisation, Organisation.objects.all().order_by('type'))
    ...
    return render_to_response('reference/organisation/organisation.html', {
        'organisation': organisation,
        'prev': prev,
        'next': next,
    })
绝对不是“重”查询集的最佳选择,但在大多数情况下,它就像一个符咒

看看,我写它就是为了解决这个问题。在这种情况下:

from next_prev import next_in_order, prev_in_order

def get_prev_and_next_page(current_page):
    page_qs = Page.objects.all()  # this could be filtered, or ordered
    prev_page = prev_in_order(current_page, page_qs)
    next_page = next_in_order(current_page, page_qs)
    return (prev_page, next_page)

谢谢,我模糊地意识到了分页器,但没有意识到我可以这样使用它(即阈值为1,实际上只是用
has_next()
has_previous()
方法将查询集包装在分页器对象中)。唯一缺少的是我没有从paginator范围的开始处开始,但是看起来我可以通过
p.object\u list.index(start\u page)
来实现这一点。这对我来说效果不好。Paginator类实际上不是用来遍历对象的。如果发现问题,请在repo上提出问题