Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 764
Magnus Avatar asked Oct 19 '25 05:10

Magnus


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"], detail=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 DjangoRESTFramework

like image 77
Innocent Peros Avatar answered Oct 21 '25 19:10

Innocent Peros



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!