Переопределение поля Django Rest Framework ModelViewSet ManyToMany Метод partial_update не работает update_or_create

У меня есть вопрос здесь

у меня две модели

Модель тега

      class Tag(models.Model):
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='author')
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

Модель профиля

      class Profile(models.Model):
    profiler = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='contour')
    bio = models.TextField(blank=True, null=True)
    tags = models.ManyToManyField(Tag, blank=True, related_name='keywords')
    image = models.ImageField(default='avatar.jpg', upload_to='images', blank=True, null=True)

    def __str__(self):
        return f'{self.profiler}'

Сериализатор тегов

      class TagSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tag
        fields = '__all__'

Сериализатор профиля

      class ProfileSerializer(serializers.ModelSerializer):
    tags = TagSerializer(many=True, read_only=True)

    class Meta:
        model = Profile
        fields = ['id',  # List All fields Exclude profiler => OneToOne field name
                  'bio', 'description',
                  'tags',
                  'image',
                  'birthDate', 'created', 'updated',
                  ]
        depth = 1

Вид профиля

      class ProfileViewSet(viewsets.ModelViewSet):
    queryset = Profile.objects.all()
    serializer_class = ProfileSerializer
    permission_classes = [IsAuthenticated]

def partial_update(self, request, *args, **kwargs):
    data = request.data

    profile_obj = Profile.objects.update(
        profiler=self.request.user,
        bio=data['bio'],
        image=data['image'],
    )

    profile_obj.save()

    for tag in data['tags']:
        tag_obj = Tag.objects.update_or_create(
            creator=self.request.user,
            name=tag['name'],  # name => Field Name in Tag Model
        )

        print(tag_obj)
        profile_obj.tags.add(tag_obj)  # tags => ManyToMany Field Name in Profile Model

    serializer = ProfileSerializer(profile_obj)

    return Response(serializer.data)

моя цель - создать новый тег, если этого имени не существует, а также обновить теги профиля

но мой код не работает, и я не знаю, почему

Может ли кто-нибудь помочь, пожалуйста?

1 ответ

Наконец я нашел решение, но все еще не хватает некоторых шагов

Сериализатор профиля

      class ProfileSerializer(serializers.ModelSerializer):
    tags = TagSerializer(many=True)  # tags = ManyToMany Field Name

    class Meta:
        model = Profile

        fields = ['id',  # List All fields Exclude profiler => OneToOne field name
                  'bio', 'description',
                  'tags',
                  'image', 'get_image',
                  'birthDate', 'created', 'updated',
                  ]

    def update(self, instance, validated_data):
        # Clear Existing Tags List Before Creating a New One By user
        instance.tags.clear()

        tags_data = validated_data.pop('tags')
        instance = super(ProfileSerializer, self).update(instance, validated_data)

        for tag_data in tags_data:
            tag_qs = Tag.objects.filter(name__iexact=tag_data['name'])

            if tag_qs.exists():
                tag = tag_qs.first()
            else:
                tag = Tag.objects.create(**tag_data, creator=self.instance.profiler)

            instance.tags.add(tag)

        return instance

Это сработало как шарм, но проблема в том, что когда я хочу частично обновить поля и не отправил поле тегов, возникает ошибка

      {
    "tags": [
        "This field is required."
    ]
}

Может ли кто-нибудь помочь сохранить мой список тегов в том виде, в котором он есть, когда в обновленных данных отсутствует поле тегов

Заранее спасибо

Другие вопросы по тегам