2014-05-11 37 views
1

下一個和以前的對象假設問答&站點。當在終點/q/<id2>處打開問題時,還應提供指向下一個/q/<id1>的鏈接,以前的問題是/q/<id3>。假設表格按照pk值或時間戳順序排列。使用鏈接的列表來查找在Django

這可以通過創建一個像我現在使用低於該方法簡單地加以解決:

def next_q(self): 
    # Ques model contain all questions 
    # this method is a model method of Ques 
    all_q = Ques.objects.all() 
    q = None 
    count = 1 
    if count < all_q.count(): 
     try: 
      q = all_q.get(pk=self.pk + count) 
      break 
     except ObjectDoesNotExist: 
      count += 1 
    return q 

不過,我認爲這種操作是足夠昂貴,它查詢所有問題(Ques對象)時請求一個問題/q/id

一種可能的方式我看到的是用鏈表下一個&以前的對象的ID可以被存儲在當前對象的想法。

有可能是在Ques模型兩個場作爲這樣

class Ques(models.Model): 
    prev_q_id = models.IntegerField() 
    next_q_id = models.IntegerField() 

這些每當創建了新的對象QUES更新,編輯,刪除。這確保我只會查詢一個單一的對象。但是,我想知道這是否是一種好方法。如果不是我能做什麼?

回答

0

用鏈表的方法是可行的,但你並不需要改變你的數據模型來支持你想要什麼。相反,您可以簡單地爲所有比主鍵更大的問題創建一個光標,然後閱讀第一個問題。

記住objects.all()實際上並不讀取所有對象。它將簡單地爲數據創建一個遊標。您可以將光標看作數據庫的「操作計劃」,以瞭解如何檢索數據。只有當你真正獲取數據時,它纔會開始讀取數據庫記錄。

你想要的基本上是在SQL中。

select * from Question where pk > question.pk order by pk 

在Django這會是這樣的

all_q = Ques.objects.all() 
all_q.filter(pk__gt=question.pk) 
all_q.order_by('pk') # not really necessary as this is done implicitly 
next_q = all_q.first() 

對於以前的記錄,你可以做同樣的,但使用相反的順序或直接撥打「最後」,而不是第一個。

1

使用上的有序結構的鏈表是沒有意義的,因爲你的數據庫已經爲您提供一個有序的記錄列表中的d您可以根據您的需要訂購你的數據達到你想要的任何項目。

這裏有一個方法,將返回你想要的東西

class Ques(Model): 
    .... 

    @classmethod 
    def get_next(cls, current_id): # current_id is the id of current record 
     try: 
      return cls.objects.filter(id__gt=current_id).order_by("id")[0] 
     except: 
      return None 

    @classmethod 
    def get_previous(cls, current_id): 
     try: 
      return cls.objects.filter(id__lt=current_id).order_by("-id")[0] 
     except: 
      return None 

使用classmethod在這裏更加有用,您只需獲得下一首或上最接近的紀錄。如果沒有記錄,那麼你得到None