2017-08-17 7 views
1

これは何が問題になるのか理解できません。私は新たに形成された問題があるので、私はthis original questionから新しい質問を開きます。私は、ネストされたシリアライザをしたいのですが既存のオブジェクトでDjango Rest Frameworkにネストされたシリアライザを作成する際の問題

はPOSTリクエストでこのJSONを受け入れて、それを保存します。

{ 
    "id": 1, 
    "sender": { 
     "id": 2, 
     "name": "anotherUser", 
     "email": "[email protected]" 
    }, 
    "recipients": [{ 
     "id": 1, 
     "name": "aUser", 
     "email": "[email protected]" 
    }], 
    "subject": "asdf", 
    "body": "asdf", 
    "read": false 
} 

だからここに私のSerializers.py

class UserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = ('id', 'name', 'email') 
     extra_kwargs = { 
      'id': { 
       'validators': [UnicodeUsernameValidator()], 
      } 
     } 



class MessageSerializer(serializers.ModelSerializer): 
    sender = UserSerializer(read_only=True) 
    recipients = UserSerializer(many=True,read_only=True) 



    class Meta: 
     model = Message 
     fields = ('id', 'subject', 'body', 'read', 'sender', 'recipients') 


    def create(self, validated_data): 
     sender_data = validated_data.pop('sender') 
     recipient_data = validated_data.pop('recipients') 
     message = Message.objects.create(**validated_data) 

     for user in recipient_data: 
      user= User.objects.get(id=user['id']) 
      message.recipients.save(user) 

     for user in sender_data: 
      user= User.objects.get(id=user['id']) 
      message.sender.save(user) 
     return message 

そして、ここにされています私のModels.py

class User(models.Model): 
    # TODO Make user idNum a UUIDField 
    id = models.IntegerField(primary_key=True) 
    name = models.CharField(max_length=30) 
    email = models.CharField(max_length=75) 

    def __str__(self): 
     return self.name 


class Message(models.Model): 
    # TODO make message id a UUIDField 
    id = models.IntegerField(primary_key=True) 
    subject = models.CharField(max_length=250) 
    body = models.CharField(max_length=5000) 
    read = models.BooleanField(default=False) 
    sender = models.ForeignKey(User, related_name='message_sender', null=True, blank=True) 
    # TODO create many to one relationship between recipients and messages 
    recipients = models.ForeignKey(User, related_name='message_recip', null=True, blank=True) 

このコードでは、/ messages/'sender'にKeyerrorを取得しています。なぜ私はこれを得ているのか分かります!これは、Sender ForeignKeyが検証されていないためです。まあいいよ。これは、送信者のシリアライザ宣言のread_only引数が原因である可能性があります。

class MessageSerializer(serializers.ModelSerializer): 

sender = UserSerializer() 
recipients = UserSerializer(many=True) 

これは検証の問題を解決します。それは次のようになりますので

だから、私は宣言のオフREAD_ONLY引数を取りました。しかし、私は今、/ messages/'Nonetype'オブジェクトにAttributeErrorがあり、 'save'属性がないことがわかりました。ここでトレースバックです:

トレースバック:

File "/Users/kevinyoung/AbstractPlayEnv/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner 
    41.    response = get_response(request) 

File "/Users/kevinyoung/AbstractPlayEnv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 
    187.     response = self.process_exception_by_middleware(e, request) 

File "/Users/kevinyoung/AbstractPlayEnv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 
    185.     response = wrapped_callback(request, *callback_args, **callback_kwargs) 

File "/Users/kevinyoung/AbstractPlayEnv/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view 
    58.   return view_func(*args, **kwargs) 

File "/Users/kevinyoung/AbstractPlayEnv/lib/python3.6/site-packages/django/views/generic/base.py" in view 
    68.    return self.dispatch(request, *args, **kwargs) 

File "/Users/kevinyoung/AbstractPlayEnv/lib/python3.6/site-packages/rest_framework/views.py" in dispatch 
    489.    response = self.handle_exception(exc) 

File "/Users/kevinyoung/AbstractPlayEnv/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception 
    449.    self.raise_uncaught_exception(exc) 

File "/Users/kevinyoung/AbstractPlayEnv/lib/python3.6/site-packages/rest_framework/views.py" in dispatch 
    486.    response = handler(request, *args, **kwargs) 

File "/Users/kevinyoung/PycharmProjects/AbstractPlay/accounts/views.py" in post 
    21.    serializer.save() 

File "/Users/kevinyoung/AbstractPlayEnv/lib/python3.6/site-packages/rest_framework/serializers.py" in save 
    215.    self.instance = self.create(validated_data) 

File "/Users/kevinyoung/PycharmProjects/AbstractPlay/accounts/serializers.py" in create 
    33.    message.recipients.save(user) 

Exception Type: AttributeError at /messages/ 
Exception Value: 'NoneType' object has no attribute 'save' 
Request information: 
USER: AnonymousUser 

GET: No GET data 

POST: No POST data 

FILES: No FILES data 

COOKIES: No cookie data 

だから私は、デバッグを開始し、そのライン上の

user= User.objects.get(id=user['id']) 

ユーザーが "< accounts.models.DoesNotExist>"

を入力するように設定されている注意してください

さて、それは意味がある、それは戻ってきているユーザーは実際にはユーザーではありません...面白いです。私はドキュメントをよく見ていました。メッセージが送信されたときに新しいユーザーを作成したくない場合でも、おそらく私はそれを操作できます。

だから私はこのように、ユーザー変数に格納されて注文した辞書ではなく、新しいユーザーオブジェクトを作成するユーザーオブジェクト「を取得します」という行変更してみてください:

user= User.objects.get(id=user['id']) 

をそして今、私user.idでUniqueConstraintエラーが発生する

私は同じユニークIDを持つ新しいユーザーを作成しようとしていました。私の問題は、私はちょうどここからどこに行くべきか分からない。自分のユーザーモデルでstrメソッドと関係がありますか?しかし、私の変更は役に立たないようです。

答えて

0

まず

extra_kwargs = { 
     'id': { 
      'validators': [UnicodeUsernameValidator()], 
     } 
    } 

IDが検証を必要とする理由、奇妙なようですか?

第2に、そして最も重要なのは、メッセージのリストを取得したいと思われるが、トレースバックではcreateと呼んでいることがわかります。
お客様の/messagesエンドポイントがどのように表示されるかは、お客様には表示されません。

私の推測によれば、GET-ではなく、POSTエンドポイントです。

第3に、recipients = models.ForeignKey(User, related_name='message_recip', null=True, blank=True)には受信者のリストはありませんが、1つのみです。

第4のmessage.recipients.save(user)は意味がありません。
お望みのものはおそらくmessage.recipients = user; user.save()

あなたのコードは、あなたが非常に多くのことに間違いをしていることを示しています。私はあなたが望むものを分解し、一歩一歩を完了することをお勧めします。

あなたは検証が、私は、ユーザー名からマッチングされたときから残ったことを

+0

1.、それを取るのを忘れて、私を思い出させてくれてありがとう「のメッセージのみのリストが、タイトルを取得」を開始することができます。 2.はい、私は実際にはPOSTにしようとしていますが、GETではありません。私はそのことを言い難く、元の投稿を編集します。 3. ListFieldを作成する必要はありますか?私が理解していないことをしたとき、私はいくつかの間違いを受けていました。 ええ、最も厄介な部分は、私は受信者と送信者のリストなしでメッセージデータを得ることができる基本的な作業例を持っていました...私はそれに戻って、この苦しみのすべて。 –

+0

何か他の点に注意してください:私はあなたの最初の観察で述べた検証を取り出しました。私は今、私のPOSTメソッドで、 "serializer.is_valid():"というレスポンスで "そのユーザーは既に存在しています"という条件を満たしていない場合、実際には何をしたいのですか?このオブジェクトに追加されるユーザー。 –

関連する問題