如何在Django Rest Framework中删除批量实例?

时间:2017-07-31 13:30:52

标签: python django django-rest-framework

在DRF的DefaultRouter网址路由器中,需要{lookup}参数才能将DELETE请求路由到destroy的{​​{1}}方法(所以,你&# 39; d请求将对象实例删除到端点ModelViewSet)。

这适用于删除单个实例,但我希望将该功能扩展为在单个请求中删除多个实例。我们假设{prefix}/{lookup}/参数名为lookup,模型名为uuid。这是Product的扩展版本:

destroy

因此,此版本在URL中接受DELETE请求和多个 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) 查询参数。现在我只需要在uuids[]

中进行路由
urls.py

不幸的是,这已经杀死了我的网址路由器。它不会解决GET到视图集中的相应方法,我不明白为什么 - 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') 我的BulkDeleteRouter应该从DefaultRouter扩展此功能?我做错了什么?

2 个答案:

答案 0 :(得分:3)

忘记将路由器网址添加到urlpatterns。我一定是个盲人。

urlpatterns += [
    url(r'^API/', include(bulk_delete_router.urls, namespace='api')),
]

答案 1 :(得分:0)

在“列表路线”路线中添加其他'delete': 'destroy'可以很好地完成工作。

class CustomRouter(DefaultRouter):
    """
    a custom URL router for the Product API that correctly routes
    DELETE requests with multiple query parameters.
    """
    routes = [
        # List route.
        Route(
            url=r'^{prefix}{trailing_slash}$',
            mapping={
                'get': 'list',
                'post': 'create',
                'delete': 'destroy', # The magic
            },
            name='{basename}-list',
            detail=False,
            initkwargs={'suffix': 'List'}
        ),
        # Dynamically generated list routes. Generated using
        # @action(detail=False) decorator on methods of the viewset.
        DynamicRoute(
            url=r'^{prefix}/{url_path}{trailing_slash}$',
            name='{basename}-{url_name}',
            detail=False,
            initkwargs={}
        ),
        # Detail route.
        Route(
            url=r'^{prefix}/{lookup}{trailing_slash}$',
            mapping={
                'get': 'retrieve',
                'put': 'update',
                'patch': 'partial_update',
                'delete': 'destroy'
            },
            name='{basename}-detail',
            detail=True,
            initkwargs={'suffix': 'Instance'}
        ),
        # Dynamically generated detail routes. Generated using
        # @action(detail=True) decorator on methods of the viewset.
        DynamicRoute(
            url=r'^{prefix}/{lookup}/{url_path}{trailing_slash}$',
            name='{basename}-{url_name}',
            detail=True,
            initkwargs={}
        ),
    ]

然后像这样使用路由器:

custom_router = CustomRouter()
custom_router.register(r'your-endpoint', YourViewSet)

urlpatterns = [
    url(r'^', include(custom_router.urls)),
]

视图集:

from rest_framework import viewsets, status
from rest_framework.response import Response
from django.db.models import QuerySet
class MachineSegmentAnnotationViewSet(viewsets.ModelViewSet):
    def destroy(self, request, *args, **kwargs):
        qs: QuerySet = self.get_queryset(*args, **kwargs)
        qs.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

希望这会有所帮助。