Сохранение вложенных объектов в поле ManyToMany с помощью DRF

Модель:

class Thread(models.Model):
"""Thread model for messages."""

    participants = models.ManyToManyField(to=User, verbose_name=_("Participants"))
    created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
    updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))

У меня есть такие сериализаторы:

class UserSerializer(serializers.ModelSerializer):
"""Serialize User model to get data from ManyToMany field to use in Thread participants."""

class Meta:
    model = User
    fields = ("id", "email")


class ThreadSerializer(serializers.ModelSerializer):
"""Serializer for create, get, edit, delete Thread."""

participants = UserSerializer(read_only=True, many=True)

class Meta:
    model = Thread
    fields = ("id", "participants", "created_at", "updated_at")

И мнения:

class ThreadListCreate(generics.ListCreateAPIView):
"""
Get threads list with participants details.
Creates a new thread with two participants.
"""
    permission_classes = (AllowAny,)
    queryset = Thread.objects.all()
    serializer_class = ThreadSerializer

Мне нужно создать новую тему с ровно двумя пользователями в "участниках", как мне это сделать? Также, чтобы назначить новых пользователей в "участники", мне нужно ввести только "id", как показано ниже:

{
"participants": [
    {"id": 1},
    {"id": 4}
    ]
}

Теперь в результате POST-кода выше я получаю следующее:

{
"id": 28,
"participants": [],
"created_at": "2022-02-16T18:22:17.524911Z",
"updated_at": "2022-02-16T18:22:17.524911Z"
}
  1. Возможно, вы хотите переименовать ваш набор представлений с ThreadListCreate на ThreadListCreateViewSet (более читабельный) и, возможно, вы можете просто использовать ModelSerailizer вместо него, поскольку в нем есть все, что вам нужно
  2. .
  3. Лучше просто разделить ваш сериализатор (Один только для целей создания)

Я сделаю что-то вроде

ViewSet

class ThreadListCreateViewSet(ModelViewset):
    permission_classes = (AllowAny,)
    queryset = Thread.objects.all()
    serializer_class = ThreadSerializer
    create_serializer_class = CreateThreadSerializer

    def get_serializer_class(self):
        if self.action == "create":
            return self.create_serilaizer_class
        return self.serializer_class

Serializer

class CreateThreadSerializer(serializers.ModelSerializer):
    participants = UserSerializer(many=True)

    def create(self, validated_data):
        instance = Thread.objects.create()
        for user in validated_data["participants"]:
            instance.participants.add(user)
        instance.save()
        return instance

Вот что я сделаю... надеюсь, это сработает для вас.

Вернуться на верх