#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')