Сообщение DRF для модели с полем «многие ко многим»

#python #django #serialization #django-rest-framework

Вопрос:

У меня есть следующие модели:

 class Tag(TimeStampModel):
    name = models.CharField(unique=True, max_length=100)
    slug = models.SlugField(max_length=100, unique=True, blank=True)
    featured = models.BooleanField(default=False, blank=True)

class Deal(VoteModel, models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='deals',
                            on_delete=models.CASCADE)
    title = models.CharField(max_length=1024, blank=False, null=False)
    slug = models.SlugField(max_length=1024, unique=True, blank=True)
    description = models.TextField(blank=False, null=False)
    poster = models.ImageField(blank=True)
    tags = models.ManyToManyField(
        Tag, blank=True)
 

И следующие сериализаторы:

 class TagSerializer(serializers.ModelSerializer):

    class Meta:
        model = Tag
        fields = ['id', 'name', 'slug', 'featured', 'created_at']


class DealSerializer(serializers.ModelSerializer):

    user = UserSerializer(many=False, read_only=True)
    tags = TagSerializer(many=True, read_only=True)
    tags_ids = serializers.PrimaryKeyRelatedField(many=True, write_only=True, queryset=Tag.objects.all())

    class Meta:
        model = Deal
        fields = '__all__'
 

Views

 class DealList(viewsets.ModelViewSet, VoteMixin):
    serializer_class = DealSerializer
    permission_classes = [IsOwnerOrAdminOrReadOnly]

    def get_queryset(self):
        return Deal.objects.all()

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)
 

Я могу получить данные, а также опубликовать их, но из-за поля «многие ко многим» ( tags ) у меня, похоже Deal , могут возникнуть некоторые проблемы, tags которые существуют только (созданы заранее и не могут быть созданы с помощью запроса на публикацию для сделки).
Я отправляю данные следующим образом:

 {
    title: 'some title',
    all_other_fields: 'some data',
    tags_ids: [2, 4]
}
 

Теги отправляются в виде массива идентификаторов тегов, но я получаю следующее сообщение об ошибке:

"Incorrect type. Expected pk value, received str."

Я добавил его только tags_ids для того, чтобы я мог выполнять операции записи на нем, так как я не мог придумать способ использовать поле tags как для чтения, так и для записи, которое возвращало бы объект при чтении и принимало идентификатор при записи.

Я прочитал много постов здесь, на Stackoverflow, но пока ничего, что работало бы для меня. Любая помощь была бы очень признательна. Спасибо.

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

1. просто чтобы убедиться, что я правильно понимаю, что вы говорите, часть ваших требований заключается в том, что теги будут созданы раньше и не могут быть созданы с помощью сделки, верно ? таким образом, вы уверены, что идентификаторы тегов, которые вы получаете, являются действительными идентификаторами

2. @JimmarThank вас за ваш ответ. Это правильно.

Ответ №1:

Попробуйте изменить свой сериализатор следующим образом

 class DealSerializer(serializers.ModelSerializer):

    user = UserSerializer(many=False, read_only=True)
    tags = serializers.PrimaryKeyRelatedField(many=True, queryset=Tag.objects.all())

    class Meta:
        model = Deal
        fields = '__all__'
 

Ответ №2:

Попробуйте сделать это таким образом.

 class DealSerializer(serializers.ModelSerializer):

    user = UserSerializer(read_only=True)
    tags = TagSerializer(read_only=True)
    class Meta:
        model = Deal
        fields = ('user', 'title', 'slug', 'description', 'poster', 'tags')