Как сделать метод удаления в django дополнительном действии? - PullRequest
0 голосов
/ 29 мая 2020

Мне удалось использовать дополнительные действия для создания конечной точки, когда я хочу отправить ImageTag (поле ManyToMany) на свое изображение. Я также смог использовать lookup_field для создания CharField вместо pk для доступа к каждому изображению.

Это моя конечная точка образца при добавлении ImageTag:

POST localhost:8000/my_app/images/IMG_123/image_tags/

Я могу отправить что-то вроде POST до конечной точки:

{"image_tags": ["Urban", "Vegetation"]}

Это мой исходный код:

#models.py
class ImageTag(models.Model):
    name = models.CharField()
    description = models.CharField()

class Image(models.Model):
    image_id = models.CharField(unique=True)
    image_tags = models.ManyToManyField(ImageTag, blank=True)
    ...

#serializers.py
class ImageSerializer(serializers.ModelSerializer):

    class Meta:
        model = Image
        fields = '__all__'

class ImageTagSerializer(serializers.ModelSerializer):
    image_tags = serializers.StringRelatedField(many=True)

    class Meta:
        model = Image
        fields = ('image_tags',)

    def to_internal_value(self, data):
        return data

#views.py
class CaptureExtraAction(viewsets.ModelViewSet):

    @action(detail=True, methods=['get', 'post', 'delete'])
    def image_tags(self, request, image_id=None):
        image = self.get_object()
        data = request.data.copy()

        image_tags = request.data.get('image_tags')
        if image_tags:
            data['image_tags'] = []
            for tag in image_tags:
                obj_, created = ImageTag.objects.get_or_create(
                    defaults={'name': tag},
                    name__iexact=tag
                    )

                image.image_tags.add(obj_)

            data['image_tags'] = image.image_tags.all()

        serializer = ImageTagSerializer(image, data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ImageTagViewSet(ImageExtraAction, viewsets.ModelViewSet):
    queryset = Image.objects.all()
    serializer_class = ImageSerializer
    lookup_field = 'image_id'
    ...

#urls.py
router.register(r'images', ImageTagViewSet, basename='image')

Моя следующая задача - разрешить методу DELETE удалить ImageTag из объекта. Например, я хочу удалить «Город» в ImageTag для изображения IMG_123, я хочу иметь такую ​​конечную точку:

DELETE localhost:8000/my_app/images/IMG_123/image_tags/Urban

также может быть:

DELETE localhost:8000/my_app/images/IMG_123/image_tags/?name=Urban

Как будет добавить это в мой текущий набор дополнительных действий?

...