How to fix 'TypeError: __init__() got an unexpected keyword argument 'sender''

11,031

You are supposed to pass a Message model instance to MessageSerializer or a dict containing data with the keys specified in fields.

In case you want to pass a dict, pass the dict to data keyword.

message_dict = {'sender': request.user, 'chat_room': ChatRoom.objects.get(id=request.data['chat_room_id']), 'content': MessageContent(text=request.data['text'])}
message_serializer = MessageSerializer(data=message_dict)

if message_serializer.is_valid():
    message_serializer.save()

Make sure you have create method implemented in your MessageSerializer.

Share:
11,031
Vincent Quirion
Author by

Vincent Quirion

Updated on June 04, 2022

Comments

  • Vincent Quirion
    Vincent Quirion almost 2 years

    I am trying to create a django model instance with a django-rest-framework serializer ModelSerializer class. This is my Serializer code:

    class MessageSerializer(serializers.ModelSerializer):
        class Meta:
            model = Message
            fields = ['sender', 'chat_room', 'content', 'sending_date']
    

    and this is my view when I try to make a model instance out of it:

    class SendMessage(APIView):
    authentication_classes = [authentication.TokenAuthentication]
    permission_classes = [permissions.IsAuthenticated]
    
    def post(self, request):
        try:
            message_type = request.data['message_type']
    
            if message_type == ('text' or 'image' or 'audio'):
    
                if message_type == 'text':
    
                    message_serializer = MessageSerializer(sender=request.user, chat_room=ChatRoom.objects.get(
                        id=request.data['chat_room_id']), content=MessageContent(text=request.data['text']))
                    message = Message(message_serializer.data)
    
                elif message_type == 'image':
                    message = MessageSerializer(sender=request.user.id, chat_room=request.data['chat_room_id'],
                                                content=MessageContent(image=request.FILES['image']))
    
                elif message_type == 'audio':
                    message = MessageSerializer(sender=request.user.id, chat_room=request.data['chat_room_id'],
                                                content=MessageContent(image=request.FILES['image']))
    
                if message.chat_room.users.all().filter(id=request.user.id).exists():
                    message.save()
    
                    if message_type == 'image':
                        resize_photo(message.content.image, MessageContent.image_width, MessageContent.image_height)
    
                    if message_type == 'audio':
                        if (not message.content.name.lower().endswith('mp4')) and os.get_size(message.content) > 25000:
                            message.delete()
                            raise FileSourceError
    
                    message.save()
                    return Response(status=status.HTTP_201_CREATED)
                else:
                    return Response(status=status.HTTP_401_UNAUTHORIZED)
    
            else:
                return Response(status=status.HTTP_400_BAD_REQUEST)
    
        except KeyError or FileSourceError:
            return Response(status=status.HTTP_400_BAD_REQUEST)
    

    This is my message model:

    class Message(models.Model):
        sender = models.ForeignKey(User, related_name='sender', on_delete=models.CASCADE)
    
        chat_room = models.ForeignKey(ChatRoom, related_name='chat_room', on_delete=models.CASCADE)
    
        content = models.OneToOneField(MessageContent, on_delete=models.CASCADE)
    
        is_read_by = models.ManyToManyField(User, related_name="is_read_by")
    
        sending_date = models.DateTimeField(auto_now_add=True)
    
        class Meta:
            ordering = ('sending_date',)
    

    However, when I run this code, I get

    TypeError: init() got an unexpected keyword argument 'sender'

    If I delete the sender argument I get

    TypeError: init() got an unexpected keyword argument 'chat_room'

    and so on. I checked if my ModelSerializer was making the right serializer fields with

    print(repr(MessageSerializer()))

    in the django python shell, and I got

    MessageSerializer():
        sender = PrimaryKeyRelatedField(queryset=User.objects.all())
        chat_room = PrimaryKeyRelatedField(queryset=ChatRoom.objects.all())
        content = PrimaryKeyRelatedField(queryset=MessageContent.objects.all(), validators=[<UniqueValidator(queryset=Message.objects.all())>])
        sending_date = DateTimeField(read_only=True)
    

    which means that my serializer has these fields (sender, chat_room, etc.) Why do I get this error and how do I fix this? Thank you for your time!