2017-06-04 96 views
0

我想創建簡單的聊天系統,我的模型:Django的對話 - get_or_create MultipleObjectsReturned

class Conversation(models.Model): 
    users = models.ManyToManyField(User, related_name='users') 
    date = models.DateTimeField(auto_now_add=True) 


class Message(models.Model): 
    user = models.ForeignKey(User) 
    conversation = models.ForeignKey(Conversation, related_name='conversation') 
    content = models.TextField() 
    date = models.DateTimeField(auto_now_add=True) 

和我的觀點:

def conversation(request, username): 
    recipient = User.objects.get(username=username) 
    conversation, created = Conversation.objects.get_or_create(
     users__in=[recipient, request.user] 
    ) 

    if created: 
     conversation.users.add([recipient, request.user]) 

我想通過創建創建多對多場會話的用戶連接。 當我去/ conversations/user_name get_or_create檢查對話是否存在,如果沒有,然後創建與當前登錄的用戶和用戶從url的新對話。

我的問題是:

MultipleObjectsReturned at /conversations/user_name 
get() returned more than one Conversation -- it returned 2! 

我該怎麼解決呢?可能它的問題與這manytomany領域..我怎麼能限制users__id查找1?

+0

對話已經存在,並有對話的兩個對象...這就是爲什麼發生錯誤... – zaidfazil

回答

0

get_or_create不適合這個。

此方法是原子假設使用正確,正確的數據庫配置和基礎數據庫的正確行爲。 但是,如果在數據庫級別對get_or_create調用中使用的kwargs沒有執行唯一性(請參閱unique或unique_together),則該方法容易出現競爭條件,從而導致多個具有相同參數的 行爲同時插入。

您的表格中沒有唯一的鍵。而且你的應用程序的本質就是無法使用唯一的密鑰。與此同時,偶爾會重複聊天消息並不是什麼大問題。因此,請繼續創建對象,而不必檢查是否存在。

還要注意,檢查現有的使用選擇然後做創建將是徒勞的。提到的比賽條件將會啓動,你仍然會得到重複的結果。

相關問題