如何将两个视图集连接到一个django url

oewdyzsn  于 2023-03-04  发布在  Go
关注(0)|答案(2)|浏览(112)

我在urls.py中连接了一个模型的标准DRF视图集,如下所示:

router = routers.SimpleRouter()
router.register("", ResourceViewSet, basename="resource")

urlpatterns = [
    path(
        "",
        include(router.urls),
        name="basic-resource-crud",
    ),
]

资源是应用中唯一的模型,所以它连接到根。另外,我想将根url上的PATCH方法连接到批量更新视图:

router = routers.SimpleRouter()
router.register("", ResourceViewSet, basename="notifications")

urlpatterns = [
    path(
        "",
        BulkResourceUpdateViewSet.as_view(),
        name="bulk-resource-update",
    ),
    path(
        "",
        include(router.urls),
        name="basic-resource-crud",
    ),
]

BulkResourceUpdateViewSet类只定义了一个patch方法。
然而,在上面的设置中,Django只会考虑urlpatterns数组中的第一条路由,而忽略另一条。
我怎样才能实现我正在寻找的网址结构:

GET   /      : ResourceViewSet
PATCH /      : BulkResourceUpdateViewSet.patch
GET   /<pk>/ : ResourceViewSet
POST  /<pk>/ : ResourceViewSet
PATCH /<pk>/ : ResourceViewSet
PUT   /<pk>/ : ResourceViewSet
m528fe3b

m528fe3b1#

您不应该像这样定义ViewSet的URL。DRF确保根据ViewSet中的方法为您提供更清晰的URL。您可以在ViewSet中包含bulk-update操作,因为它正在修改相同的资源。这使您的URL方案与REST API标准一致,并生成更清晰的URL方案。
大概是这样的

from django.urls import path, include
from rest_framework import routers, mixins, status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from your_app.models import Resource
from your_app.serializers import ResourceSerializer

class ResourceViewSet(mixins.RetrieveModelMixin,
                      mixins.CreateModelMixin,
                      mixins.UpdateModelMixin,
                      viewsets.GenericViewSet):
    queryset = Resource.objects.all()
    serializer_class = ResourceSerializer
    
    @action(methods=['PATCH'], detail=False)
    def bulk_update(self, request, *args, **kwargs):
        # Your bulk update logic here
        return Response(status=status.HTTP_200_OK)

在您的urls.py文件中,您可以通过简单的路线添加路线,如:

router = routers.SimpleRouter()
router.register('', ResourceViewSet, basename='resource')

urlpatterns = [
    path('', include(router.urls)),
]

这将确保添加以下路由:

  • GET /-资源列表
  • POST /-创建新资源
  • GET /:pk/-根据pk获取单个资源
  • PATCH /:pk/-修改由pk标识的单个资源
  • PUT /:pk/-使用所有属性修改由pk标识的单个资源
  • PATCH /bulk-update/-批量更新资源

理想情况下,即使您的项目中只有一个资源,您也应该在api/的根目录下使用资源名称作为URL的前缀,这样才能使您的项目具有可扩展性。
因此,URL应该是这样的:
GET /api/resource_name/而不是GET /来获取资源列表。

kwvwclae

kwvwclae2#

如果不更改url,就无法在当前视图集中添加此功能(如果您不想做猴子补丁解决方案)。如果您愿意更改url,则可以在视图集中添加此功能,如下所示:

class ResourceViewSet(...):
    
     @action(detail=False)
     def bulk_update(self, request):
         ...

否则,您可以让一个视图具有“列表和更新”功能,让另一个视图集具有其余功能,如下所示:

class BulkResourceListUpdateView(ListAPIView):
   # bulk update codes here         

class ResourceViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   viewsets.GenericViewSet):

     ....

更多信息请参见documentation

相关问题