Django - Сериализатор не устанавливает ManyToManyField

По какой-то причине следующий код не устанавливает атрибут hash_tags под Post. Я проверил это следующим образом: я поставил точку останова на строке return Response в view.py и проверил только что созданный объект Post и атрибут hash_tags просто вернул пустой список. Также, когда я читаю serializer.data, hash_tags также является пустым списком. Несмотря на то, что таблица HashTag явно создала хэш-тег, найденный в теле. Что происходит?

model.py

class Post(AbstractBaseModel):
    creator = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="post_creator")
    join_goal = models.ForeignKey(JoinGoal, on_delete=models.CASCADE)
    body = models.CharField(max_length=511, validators=[MinLengthValidator(5)])
    hash_tags = models.ManyToManyField(HashTag)
    type = models.CharField(
        choices=PostType.choices,
        max_length=50,
    )

class HashTag(models.Model):
    hash_tag = models.CharField(max_length=140, primary_key=True, validators=[
        MinLengthValidator(1)])

Serializer.py

class HashTagSerializer(serializers.ModelSerializer):
    class Meta:
        model = HashTag
        fields = ['hash_tag']

class PostSerializer(serializers.ModelSerializer):
    hash_tags = HashTagSerializer(many=True, read_only=True)

    class Meta:
        model = Post
        fields = ('creator', 'join_goal', 'body', 'uuid', 'created', 'type', 'updated_at', 'hash_tags')

view.py

@api_view(['POST'])
def post_create_update_post(request):
    user_uuid = str(request.user.uuid)

    request.data['creator'] = user_uuid
    request.data['type'] = PostType.UPDATE
    post_text = request.data['body']
    hash_tags_list = extract_hashtags(post_text)
    hash_tags = [HashTag.objects.get_or_create(hash_tag=ht)[0].hash_tag for ht in hash_tags_list]
    request.data['hash_tags'] = hash_tags

    try:
        with transaction.atomic():
            serializer = PostSerializer(data=request.data)
            if serializer.is_valid(raise_exception=True):
                post_obj = serializer.save()
    except Exception as e:
        return Response(dict(error=str(e),
                             user_message=error_message_generic),
                        status=status.HTTP_400_BAD_REQUEST)

    return Response(serializer.data, status=status.HTTP_201_CREATED)

Я также попробовал не устанавливать read_only=True и получил эту ошибку

это приводит к ValidationError({'hash_tags': [ErrorDetail(string='This field is required.', code='required')]}) с request.data['hash_tags']=['Test']

Вы установили read_only=True Из-за этого значение hash_tags не сохраняется в базе данных.

hash_tags = HashTagSerializer(many=True, read_only=True)

Объявите его без read_only следующим образом:

hash_tags = HashTagSerializer(many=True)

Я считаю, что вы должны переопределить метод create и update для вложенного сериализатора в serializer.py:

class HashTagSerializer(serializers.ModelSerializer):
   class Meta:
      model = HashTag
      fields = ['hash_tag']

class PostSerializer(serializers.ModelSerializer):
    hash_tags = HashTagSerializer(many=True, read_only=True)

   class Meta:
      model = Post
      fields = ('creator', 'join_goal', 'body', 'uuid', 'created', 'type', 'updated_at', 'hash_tags')

      def create(self, validated_data):
         hash_tags_data = validated_data.pop('hash_tags')
         post = Post.objects.create(**validated_data)
         for data in hash_tags_data:
            hash_tag = HashTag.objects.get_or_create(**data)
            post.hash_tags.add(hash_tag)
         post.save()
         return post
Вернуться на верх