Сохранение вложенных объектов в поле 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"
}
- Возможно, вы хотите переименовать ваш набор представлений с
ThreadListCreateнаThreadListCreateViewSet(более читабельный) и, возможно, вы можете просто использоватьModelSerailizerвместо него, поскольку в нем есть все, что вам нужно .
- Лучше просто разделить ваш сериализатор (Один только для целей создания)
Я сделаю что-то вроде
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
Вот что я сделаю... надеюсь, это сработает для вас.