2010-02-06 25 views
14

我有一個非常簡單的查詢設置和相關的通用視圖:下一頁鏈接/通用視圖

f_detail = { 
     'queryset': Foto.objects.all(), 
     'template_name': 'foto_dettaglio.html', 
     "template_object_name" : "foto", 
     } 

urlpatterns = patterns('', 
# This very include 
(r'^foto/(?P<object_id>\d+)/$', list_detail.object_detail, f_detail,), 
) 

只是用於生成照片的詳細信息頁面模板:所以沒有看法。


是否有簡單的方法可以鏈接到以前的|模板中的下一個元素 沒有手動編碼視圖?

財產以後像:

{% if foto.next_item %} 
    <a href="/path/foto/{{ foto.next_item.id_field }}/">Next</a> 
{% endif} 
+0

Mmh的你想知道嗎?是的,您可能已經提供瞭解決方案。你只需要實現'next_item'方法。 – 2010-02-06 22:44:46

+2

http://stackoverflow.com/questions/1931008/is-there-a-clever-way-to-get-the-previous-next-item-using-the-django-orm – shanyu 2010-02-06 23:00:35

+0

看到:如果我沒有注意到它以及它是關於在模型中有一個DateField或DateTimeField,這不是我的情況:我想通過(比方說)id字段來命令我的查詢集結果。 是否有預配置的方式來遍歷結果集並獲取以前的|下一個項目?還是應該設計自己的視圖並編寫_get_(next | previous)_item函數? – eaman 2010-02-07 01:55:27

回答

24
class Foto(model): 
    ... 
    def get_next(self): 
    next = Foto.objects.filter(id__gt=self.id) 
    if next: 
     return next.first() 
    return False 

    def get_prev(self): 
    prev = Foto.objects.filter(id__lt=self.id).order_by('-id') 
    if prev: 
     return prev.first() 
    return False 

你可以調整這些根據自己的喜好。我只是再次查看你的問題......爲了使它比使用if語句更容易,可以使方法返回鏈接的標記,如果存在鏈接,則返回下一個/ prev,否則不返回任何內容。那麼你只需要做foto.get_next等等。還記得查詢集是懶惰的,所以你實際上並沒有在next/prev中獲得大量的項目。

+0

謝謝,這就是我現在正在處理的:我的模型的下一個/ prev鏈接的自定義方法。感謝這個例子,這些(id__gt | lt = self.id)看起來好多了,無論我在想什麼。 非常感謝。 – eaman 2010-02-07 21:24:08

+0

'get_prev'和'get_next'返回對象,所以必須使用'foto.get_next.id'來獲取next/prev的pk。謝謝! – curtisp 2016-07-27 19:14:54

+0

謝謝,順便說一句。沒有必要檢查'next'和'pref'。如果找不到任何東西,first()將返回None – MartinM 2017-06-20 08:01:59

1

如果您接受Model.objects.all()作爲您的查詢集,並且您可以通過日期字段獲取下一個/上一個項目(通常是使用auto_now_add = True的'created'字段將提供相同的順序作爲對象ID),您可以使用get_next_by_foo() and get_previous_by_foo(),其中'foo'是日期字段。

對於來自更復雜QuerySet的下一個/上一個鏈接,使用Paginator with threshold set to one看起來可能是最好的選擇。

7

以上Foto版本有幾個缺點:

  • 做一個布爾評價像if next:可能會很慢,因爲它基本上加載整個QuerySet結果。使用next.exists()或嘗試/除了在我的版本中。
  • get_prev()結果是錯誤的,因爲在這種情況下需要反轉排序。

所以FWIW這裏是我的版本,這是一個通用的主鍵:

def get_next(self): 
    """ 
    Get the next object by primary key order 
    """ 
    next = self.__class__.objects.filter(pk__gt=self.pk) 
    try: 
     return next[0] 
    except IndexError: 
     return False 

def get_prev(self): 
    """ 
    Get the previous object by primary key order 
    """ 
    prev = self.__class__.objects.filter(pk__lt=self.pk).order_by('-pk') 
    try: 
     return prev[0] 
    except IndexError: 
     return False