2009-11-25 93 views
0

我想使消息視圖顯示導致該消息的所有其他消息。原始消息將不會有response_to值並應終止遞歸。有一個更好的方法嗎? (我看速度超過內存,因爲線程通常不應超過10 - 20條消息)。django模型實例的遞歸函數

def get_thread(msg,msg_set=[]): 
    """ 
    This will get all the messages that led up to any particular message 
    it takes only a message, but if the message isn't the first message 
    in a thread it appends it to a message list to be returned. 

    the last message in the list should be the first message created 
    """ 
    if msg.response_to: 
     return get_thread(msg.response_to, msg_set+[msg]) 
    return msg_set+[msg] 


# Create your models here. 
class Message(models.Model): 
    body = models.TextField() 
    sender = models.ForeignKey(User,related_name='sender') 
    recipients = models.ManyToManyField(User,related_name='recipients') 
    timestamp = models.DateTimeField(default=datetime.datetime.now) 
    response_to = models.ForeignKey(Message,related_name='response_to') 

    def thread(self): 
     return get_thread(self) 

回答

3

是的。不使用遞歸。

def get_thread(msg): 
    messages = [] # empty message set 

    while msg.response_to: 
     messages.append(msg) 
     msg = msg.response_to 

    messages.append(msg) # will append the original message 

    return messages 
+0

你知道哪種方法會消耗更多的內存嗎? –

+0

通常遞歸方法會消耗更多內存 – ikkebr

+0

如果代碼是對另一個消息的響應,您的代碼實際上會追加初始消息兩次。但我的想法足以使用這個答案。 –

0

如果你想限制遞歸深度,增加一個遞減計數器:

class Message(Model): 

    def get_thread(self, max_length = 10): 
     if self.response_to: 
      thread = response_to.get_thread(max_length-1) 
     else: 
      thread = [] 
     thread.append(self) 
     return thread 

遞歸通常比循環更慢,而且通常會消耗更多的內存(因爲你需要做棧有趣的事情要實現它),如果你只有1000(甚至更多)深度,這並不是什麼大問題。