How can I get previous and next objects from a filtered, ordered queryset?

后端 未结 3 2150
野趣味
野趣味 2021-02-10 12:15

I have a page based on a model object, and I want to have links to the previous and next pages. I don\'t like my current solution because it requires evaluating the entire query

相关标签:
3条回答
  • 2021-02-10 12:40

    I'm new to Python and Django, so maybe my code is not optimal, but check this out:

    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)
    

    And in view something like that:

    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,
        })
    

    Definitely not optimal for «heavy» querysets, but in most cases works like a charm. :)

    0 讨论(0)
  • 2021-02-10 12:43

    Sounds like something the Paginator set to a threshold of 1 would do well at.

    # 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)
    

    Documentation here and here.

    0 讨论(0)
  • 2021-02-10 12:53

    Check out django-next-prev, I wrote it to solve this exact problem. In this case:

    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)
    
    0 讨论(0)
提交回复
热议问题