如何实现REST API中带slug与pk双标识的两级嵌套资源路由?
实现方案
你可以通过两种主流方案实现该两级嵌套路由,以下是完整代码示例:
方案1:使用drf-nested-routers第三方包(推荐,适合多嵌套路由场景)
这是DRF生态中处理嵌套路由的常用工具,代码可维护性更高。
- 安装依赖
pip install drf-nested-routers
- 编写单条评论操作的视图集
新增单独的CommentViewSet处理单条评论的查、改、删操作:
from rest_framework import viewsets, mixins, permissions from .models import Comment from .serializers import CommentSerializer class CommentViewSet( mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet ): serializer_class = CommentSerializer # 按需配置权限,比如仅评论作者可修改/删除 permission_classes = [permissions.IsAuthenticatedOrReadOnly] def get_queryset(self): # 过滤当前照片下的所有评论,自动拦截不属于当前照片的评论请求返回404 return Comment.objects.filter(photo__slug=self.kwargs["slug_name"])
- 注册嵌套路由
在你的urls.py中注册父子路由:
from rest_framework.routers import DefaultRouter from rest_framework_nested import routers from .views import PhotoViewSet, CommentViewSet # 注册父级photos路由 router = DefaultRouter() # 确保你的PhotoViewSet已经设置了lookup_field = "slug",才能正常解析slug参数 router.register(r"photos", PhotoViewSet, basename="photos") # 注册嵌套的comments路由 comments_router = routers.NestedSimpleRouter(router, r"photos", lookup="slug_name") comments_router.register(r"comments", CommentViewSet, basename="photo-comments") urlpatterns = [ # 你的其他原有路由 ] + router.urls + comments_router.urls
注册后会自动生成你需要的photos/{slug_name}/comments/{pk}路由,支持GET、PATCH、DELETE操作,且和你之前通过@action实现的评论列表/创建路由不冲突。
方案2:手动注册路由(无第三方依赖)
如果只需要这一条嵌套详情路由,不需要引入额外依赖,直接手动绑定路径即可:
在urls.py中添加以下路径:
from django.urls import path from .views import CommentViewSet urlpatterns = [ # 你的其他原有路由,包括之前注册的photos路由和@action生成的评论路由 path( "photos/<slug:slug_name>/comments/<int:pk>/", CommentViewSet.as_view({ "get": "retrieve", "patch": "partial_update", "delete": "destroy" }), name="photo-comment-detail" ), ]
该方案和方案1效果完全一致,仅适合嵌套路由数量少的场景。
注意:两种方案都需要你提前配置好Comment的序列化器,按需添加权限校验逻辑即可。
内容的提问来源于stack exchange,提问作者Risker
相关产品推荐
相关产品推荐

