Django rest framework: how to make a view to delete multiple objects?

Viewed 764

I am building a simple Photos-Albums app with Django Rest Framework (DRF). I would like to be able to delete multiple albums at once by supplying an array of ids. I am using viewsets.ModelViewSet for the basic views.

class AlbumViewSet(viewsets.ModelViewSet):
    queryset = Album.objects.all()
    serializer_class = AlbumSerializer

I have managed to create a view to show the albums before the delete operation by adding this function to my views.py file.

@api_view(['GET', 'DELETE'])
def delete_albums(request):
    """
        GET:    list all albums
        DELETE: delete multiple albums
    """

    if request.method == 'GET':
        albums = Album.objects.all()
        serializer = AlbumSerializer(albums, many=True)
        return Response(serializer.data)

    elif request.method == 'DELETE':
        ids = request.data
        albums = Album.objects.filter(id__in=ids)
        for album in albums:
            album.delete()
        serializer = AlbumSerializer(albums, many=True)
        return Response(serializer.data)

If I run curl -X delete -H "Content-Type: application/json" http://localhost:8000/albums/delete -d '{"data":[1,2,3]}' then it will delete albums with ids 1,2,3.

This is OK, except that:

  • It's not class-based, and I'd prefer to have everything class-based if possible
  • I would prefer to have a form in the view that lets me input an array e.g. [1,2,3], hit a delete button, and then see the results of the query in the browser, much like when one posts a new object through the interface.

Can anyone please outline how to achieve that? Thanks!

1 Answers

You can use the action decorator

from rest_framework.decorators import action
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.request import Request

#import your model and serializer classes

class AlbumViewSet(viewsets.ModelViewSet):
    queryset = Album.objects.all()
    serializer_class = AlbumSerializer

    @action(methods=["DELETE"], details =False, )
    def delete(self, request:Request):
        delete_id =request.data
        delete_albums = self.queryset.filter(id__in=delete_id)
        
        delete_albums.delete()
        return Response( self.serializer_class(delete_albums,many=True).data) 

assuming your modelViewSet api point was /api/albums you could now make a delete request to /api/albums/delete

You could check out the full document on viewsets at ViewSet and on how to use action decorator provided by the django rest framework

Related