在Django现有路由模型下,如何获取指定Story的关联Episode?
获取指定Story对应所有Episode的实现方案
嘿,我来帮你搞定这个需求!结合你现有的Django REST Framework(DRF)配置和模型结构,这里有几种实用的实现方式,你可以根据自己的业务场景选最合适的:
方法一:使用嵌套路由(最符合RESTful规范)
这种方式会把Episode作为Story的子资源,URL结构变成/stories/<story_id>/episodes/,逻辑清晰且符合REST设计风格。
步骤:
- 先确保安装了
drf-nested-routers(没装的话执行pip install drf-nested-routers) - 修改路由配置:
from rest_framework_nested import routers # 根路由 router = routers.DefaultRouter() router.register('', StoryView, basename='stories') # 基于Story路由创建嵌套的Episode子路由 story_router = routers.NestedDefaultRouter(router, '', lookup='story') story_router.register('episodes', EpisodeView, basename='story-episodes') # 将路由加入URL配置 urlpatterns = [ # 其他业务路由... path('', include(router.urls)), path('', include(story_router.urls)), ]
- 调整
EpisodeView的查询逻辑,自动从URL参数中获取Story ID并过滤:
class EpisodeView(viewsets.ModelViewSet): queryset = Episode.objects.all() serializer_class = EpisodeSerializer # 替换成你实际的序列化器 def get_queryset(self): # 从URL的lookup参数中提取story_id story_id = self.kwargs.get('story_pk') if story_id: return Episode.objects.filter(story_id=story_id) # 无story_id时返回全部Episode,保留原有接口功能 return super().get_queryset()
现在访问/stories/1/episodes/就能获取ID为1的Story下的所有Episode了。
方法二:通过查询参数过滤(无需改动现有路由)
如果你不想调整现有路由结构,可以给episodes接口添加story_id查询参数来实现过滤。
修改EpisodeView的查询逻辑:
class EpisodeView(viewsets.ModelViewSet): queryset = Episode.objects.all() serializer_class = EpisodeSerializer def get_queryset(self): queryset = super().get_queryset() # 从URL的查询参数中获取story_id story_id = self.request.query_params.get('story_id') if story_id: queryset = queryset.filter(story_id=story_id) return queryset
现在访问/episodes/?story_id=1就能得到ID为1的Story对应的所有Episode了。
方法三:在StoryView中添加自定义Action
这种方式可以让你通过/stories/<pk>/episodes/接口直接获取指定Story的Episode,同时保留原有路由结构不变。
修改StoryView:
from rest_framework.decorators import action from rest_framework.response import Response class StoryView(viewsets.ModelViewSet): queryset = Story.objects.all() serializer_class = StorySerializer # 添加自定义action,detail=True表示需要传入Story的pk @action(detail=True, methods=['get']) def episodes(self, request, pk=None): story = self.get_object() # 获取当前Story关联的所有Episode episodes = story.episode_set.all() # 用Episode的序列化器处理数据 serializer = EpisodeSerializer(episodes, many=True) return Response(serializer.data)
现在访问/stories/1/episodes/就能拿到ID为1的Story的所有Episode了。
内容的提问来源于stack exchange,提问作者Danabek Duisekov
相关产品推荐
相关产品推荐

