2017-06-04 8 views
0

をMultipleObjectsReturned:Djangoの会話 - get_or_createは私のモデル、私は簡単なチャットシステムを作成したい

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

会話は既に存在し、会話のオブジェクトは2つあります...そのため、エラーが発生しました... – zaidfazil

答えて

0

get_or_createはこれには適していません。

このメソッドは、正しい使用法、適切なデータベース の構成、および基礎となるデータベースの動作を正しく仮定しています。 しかし、 のget_or_create呼び出し(uniqueまたはunique_togetherを参照)で使用されるkwargのデータベースレベルで一意性が強制されていない場合、 このメソッドは同じパラメータを持つ複数の 行になる可能性のある競合状態になりがちです同時に挿入されます。

テーブルには一意のキーがありません。また、アプリの性質上、固有のキーを使用できないという性質があります。同時に、非常に時折繰り返されるチャットメッセージは大したことではありません。だから、存在を確認することを邪魔することなくオブジェクトを作成してください。

また、selectを使用して既存のものをチェックしてからcreateを実行するのは無駄でしょう。言及された競争状態はキックインし、あなたはまだ重複で終わるでしょう。

関連する問題