2012-10-04 70 views
0

我已經試圖找出爲什麼我沒有返回PrivateMessages列表。有時候一對不同的眼睛可以馬上發現,所以我在這裏發佈這個希望有人發現錯誤。django視圖中的無限循環

這是一個獲取20個或更少的私人消息並刪除同一用戶的重複消息的函數,即每個用戶只有1條消息將在返回的pm批處理中進行。

它還排除處於「靜音」列表中的用戶。這些工作正常,所以我不認爲這與沉默位有關。

在調用remove_duplicate_users之後,我得到最後一個對象的ID,以便在下一個查詢中使用它。

我沖洗並重復,直到列表中有20個對象準備返回或查詢不返回任何內容。

def get_private_messages(request): 
    ss = Silenced.objects.filter(user=request.user) 
    last_pm_id = None 
    n = 20 
    bl = [] 
    while True: 
     if last_pm_id: 
      pmr = PrivateMessage.objects.filter(user=request.user,hidden=False,id__lt=last_pm_id).exclude(sender__in=[s.brat for s in ss]).order_by('-id')[:n] 
     else: 
      pmr = PrivateMessage.objects.filter(user=request.user,hidden=False).exclude(sender__in=[s.brat for s in ss]).order_by('-id')[:n] 
     l = list(pmr) 
     bl = bl + l 
     bl = remove_duplicate_senders(bl) 
     n = 20 - len(bl) 
     last_pm_id = bl[-1].id 
     if len(bl) >= 20 or not pmr: 
      break 

    return HttpResponse(bl) 

這是刪除重複的用戶消息的功能。它對於名爲pin或note的用戶來說是個例外,如果pm.info1匹配只有前10個晚上的welcome。

def remove_duplicate_senders(pmr): 
    l = [] 
    a = False 
    for p in pmr: 
     a = True 
     if p.sender.username in ['pin','note'] or p.info1=='welcome': 
      l.append(p) 
      continue 
     for px in l: 
      if p.sender.username == px.sender.username: 
       a = False 
       break 
     if a: 
      l.append(p) 
    return l 

我用來測試的用戶有超過60分的,但我得到什麼似乎是一個無限循環,當我嘗試檢索前20分的。它可以和其他用戶一起工作,但是在第一個用戶中下訂單的方式會導致錯誤。

任何有識之士在此表示讚賞,謝謝。

+0

第二位代碼中的循環有點奇怪:你在循環中向'l'添加東西,然後仍然在循環中通過'l'本身。這是正確的還是存在縮進問題? –

+0

對不起,我複製了第一個功能錯誤,現在我修好了。 – madprops

+0

呃這樣深奧的使用變量名稱。我在這裏看到了一些不一致的地方:'return Httpresponse(pms)'(where pms defined)and'sender__in = [s.breakt for s in ss]','sender__in = [s.brat for s in ss] '(相信應該是一樣的)。你寫的函數沒有任何無限循環的副作用,我可以告訴。 –

回答

0

我覺得你的休息條件是無效的:

if len(bl) >= 20 or not pmr: 
    # Stop if I have more than 20 messages? Shouldn't I continue filtering? 
    break 

應該是:

if n >= 0: 
    # Stop only if I have 20 or less [n = 20 - len(bl)], continue otherwise 
    break 

我可能誤解了一些東西,但你的while循環的最後一部分是與副作用的位。請考慮重寫代碼以使其更清晰。

+0

如果少於20個,我想獲得前20個消息。所以n從20開始減少到20 - len(bl)即20減去已經在大列表中的消息。所以我檢查len(bl)是否已經是20(或者更多,如果有什麼奇怪的事情發生的話)或者如果查詢不再返回任何東西(不是pmr)。你的建議n> = 0從開始是真實的。如果有少於20點的話,n <= 0的其他方式可能不是真的。 – madprops

+0

如果有40條消息,則檢查'-20> = 0',這是錯誤的,並且不會中斷。如果你有16條消息,那就是'4> = 0',你會中斷。無論哪種情況,我的推理在代碼行爲方面可能存在問題,但絕對不符合您的破解條件。 –

+0

如果我只有16條消息,首先它們中的一些可能會被remove_duplicate_users刪除,然後讓我們留下7條消息。 n將變爲13,last_pm_id將成爲大列表中最後一條消息的ID,假設爲234.在這種情況下,它們都會失敗,因爲bl不是> = 20且pmr不是空的。然後在下一次迭代時,它將搜索一個id低於last_pm_id的pm,它將返回空。 bl將保持不變。它會失敗bl> = 20,但pmr將是錯誤的,那麼它應該通過。我刪除remove_duplicate_users循環休息就好了,所以問題就在那裏.. – madprops

0

事實證明,同一用戶的太多pm是連續的,所以當它試圖獲得n個私人消息時,它永遠不會達到20個。我添加了一個函數來創建一個列表bl中的所有用戶並將其排除在查詢中。感謝您的回覆。