DRF создает экземпляр с вложенным сериализатором, вызывающим исключение для сериализатора.is_valid

#django #django-rest-framework

Вопрос:

Контекстуализация

У меня есть следующий сериализатор, который имеет вложенный сериализатор для возврата имени пользователя вместо идентификатора

     class RoomSerializer(serializers.ModelSerializer):
        participants = ParticipantSerializer(many=True) # Nested serializer
    
        class Meta:
            model = Room
            fields = '__all__'

I crated the following ListView under this url => `localhost:8000/api/rooms/<username>/`


class RoomList(generics.ListCreateAPIView):
    serializer_class = RoomSerializer

    def get_queryset(self):
        return Room.objects.filter(participants__username=self.kwargs['username'])

    def create(self, request, *args, **kwargs):
        print(request.data)
        return super().create(request, *args, **kwargs)
 

Первый выпуск

Первое, что произошло, это то, что я отправил следующие данные

 data = {
    'participants': ['foo', 'foo1']
}
 

и вернул ошибку 400 со следующими данными

 {"participants": [
        {"non_field_errors": ["Invalid data. Expected a dictionary, but got str."]},
        {"non_field_errors": ["Invalid data. Expected a dictionary, but got str."]}
    ]
}
 

Поэтому я изменил данные запроса, чтобы они выглядели как полезная нагрузка, когда я делаю запрос get на эту конечную точку.

 data = {
    'participants': [
        {username: 'foo'},
        {username: 'foo2'},
    ]
}
 

Второй вопрос

Все еще возвращаю код 400 с этим ответом.

 {"participants": [
        {"username": ["A user with that username already exists."]},
        {"username": ["A user with that username already exists."]}
    ]
}
 

что мне нужно

На «GET» мне нужен список всех комнат, участником которых является пользователь, и в каждой комнате должен быть список с именем пользователя (есть необходимость во вложенном сериализаторе, потому что без него список составлялся по идентификатору)

В разделе «СООБЩЕНИЕ» мне нужно создать новую комнату, единственное требуемое поле-участник, ради этого поста я приведу модель комнаты ниже.

 class Room(models.Model):
    room_name = models.CharField(max_length=28, blank=True, null=True)
    participants = models.ManyToManyField(CustomUser)
    messages = models.ManyToManyField(Message, blank=True)
    is_group = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.pk)
 

Комментарии:

1. Гораздо проще создать вложенный сериализатор на serializers.py . Кроме того, конечная точка ищет словарь, а не одну строку. Вы отправляете данные неправильно. Сначала вам нужно переписать метод create, чтобы разрешить такое поведение, во-вторых, вам нужно передать данные как есть.