In DRF's DefaultRouter url router, it requires a {lookup} parameter to route DELETE requests to the destroy method of a ModelViewSet (so, you'd make your request to delete an object instance to the endpoint {prefix}/{lookup}/).
This is fine for deleting a single instance, but I'd like to extend that functionality to deleting multiple instances on a single request. Let's say the lookup parameter is called uuid and the model is called Product. Here's an extended version of destroy:
def destroy(self, request, uuid=None):
"""
Overridden method allows either url parameter of single UUID
(to delete a single instance), or multiple query parameters `uuids`
to delete multiple instances.
"""
if not uuid:
uuids = request.query_params.get('uuids', None)
if not uuids:
return Response(status=status.HTTP_404_NOT_FOUND)
if len(uuids) != Product.objects.filter(uuid__in=uuids).count():
return Response(status=status.HTTP_404_NOT_FOUND)
Product.objects.filter(uuid__in=uuids).delete()
else:
instance = self.get_object(uuid)
if not instance:
return Response(status=status.HTTP_404_NOT_FOUND)
instance.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
So this version takes a DELETE request and multiple uuids[] query parameters in the url. Now I just need to route it in urls.py:
from rest_framework.routers import DefaultRouter, Route
class BulkDeleteRouter(DefaultRouter):
"""
a custom URL router for the Product API that correctly routes
DELETE requests with multiple query parameters.
"""
def __init__(self, *args, **kwargs):
super(BulkDeleteRouter, self).__init__(*args, **kwargs)
self.routes += [
Route(
url=r'^{prefix}{trailing_slash}$',
mapping={'delete': 'destroy'},
name='{basename}-delete',
initkwargs={'suffix': 'Delete'}
),
]
bulk_delete_router = BulkDeleteRouter()
bulk_delete_router.register(r'product', ProductViewSet, base_name='product')
This, unfortunately, has killed my url router. It won't resolve GET to the appropriate methods in the viewset, and I don't understand why - isn't my BulkDeleteRouter supposed to extend this functionality from the DefaultRouter? What did I do wrong?