2009-11-07 11 views
5

我有一個基於模型對象的頁面,我想鏈接到上一頁和下一頁。我不喜歡我當前的解決方案,因爲它需要評估整個查詢集(獲取ids列表),然後再查詢兩個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是連續的。

回答

8

聽起來就像Paginator設置爲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) 

Documentation here and here

+1

謝謝,我隱約意識到分頁程序,但並沒有意識到,我可以用它像(與1閾值,即,實際上只是包裹查詢集的分頁程序對象用'has_next()','has_previous()'方法)。唯一缺少的是我並沒有從paginator範圍的開始處開始,但它看起來像我可以通過'p.object_list.index(start_page)'得到這個。 – 2009-11-07 13:32:36

+1

這最終不適合我。 Paginator類實際上並不適用於遍歷對象。 – 2016-08-13 08:02:51

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

絕對不是最佳對於「重」查詢集,但在大多數情況下,它就像一個魅力。 :)

1

退房django-next-prev,我寫它來解決這個確切的問題。在這種情況下:

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 = prev_in_order(current_page, page_qs) 
    return (prev_page, next_page) 
相關問題