【问题标题】:Nested routes with APIViews in Django Rest Framework在 Django Rest Framework 中使用 APIView 嵌套路由
【发布时间】:2017-10-01 15:19:41
【问题描述】:

我正在编写我的学校项目,构建 Django Rest API。我还有下一个实体:ProfilesAlbumsImagesCommentsLikes

我想要的是以这种方式访问​​资源: api/v1/profiles/1/albums --> 从 id 为 1 的个人资料中获取所有专辑

在我找到的示例中,使用了ViewSet,而不是我想使用的APIView(我真的是新手,我什至不知道我可以将ViewSet 用于CRUID 操作)。 接下来我尝试实现:

还有很多其他的,但我无法让它工作......

如果有详细教程,请参考,我真的要快。

谢谢大家!

【问题讨论】:

    标签: python django rest api nested


    【解决方案1】:

    我通过过滤get_querysetget_object 解决了这个问题。有其他需要帮助的人的例子:

    urls.py

    url(r'(?P<profile_id>\d+)/albums/(?P<album_id>\d+)/images/(?P<image_id>\d+)/comments/(?P<comment_id>\d+)/?$',CommentDetailAPIView.as_view(), name='profile-album-image-comment'),
    

    views.py

    class GetCommentsAPI(ListAPIView):
    """
    
    """
    serializer_class = CommentSerializer
    filter_backends = [SearchFilter]  # ово мора бити низ!
    authentication_classes = [AllowAny]
    
    def get_queryset(self, *args, **kwargs):
       # ipdb.set_trace(context=5)
        profile_id = self.kwargs.get("profile_id")
        if not profile_id:
            return Response({"status": "fail"}, status=403)
    
        profile = Profile.objects.get(pk=profile_id)
    
        album_id = self.kwargs.get("album_id")
        if not album_id:
            return Response({"status": "fail"}, status=403)
        album = Album.objects.get(pk=album_id, owner_id=profile_id)
    
        if not album:
            return Response({"status": "fail"}, status=404)
    
        image_id = self.kwargs.get("image_id")
        if not image_id:
            return Response({"status": "fail"}, status=403)
        image = Image.objects.get(pk=image_id, album_id=album_id)
    
        queryset_list = Comment.objects.filter(image__pk=image_id)
        return queryset_list
    
    class CommentDetailAPIView(DestroyModelMixin, UpdateModelMixin, RetrieveAPIView):
    """
    
    """
    queryset = Comment.objects.all()
    serializer_class = DetailedCommentSerializer
    permission_classes = [IsAuthenticatedOrReadOnly]
    
    def get_object(self):
        profile_id = self.kwargs.get("profile_id")
        profile = Profile.objects.get(pk=profile_id)
        if not profile:
            return JsonResponse({"status":"fail","code":404})
    
        album_id = self.kwargs.get("album_id")
        album = Album.objects.get(pk=album_id)
        if not album:
            return JsonResponse({"status": "fail", "code": 404})
    
        image_id = self.kwargs.get("image_id")
        image = Image.objects.get(pk=image_id)
        if not image:
            return JsonResponse({"status": "fail", "code": 404})
    
        comment_id = self.kwargs.get("comment_id")
        if not comment_id:
            return JsonResponse({"status": "fail", "code": 404})
    
        comment = get_object_or_404(queryset=Comment.objects.all(), pk=comment_id, image__pk=image_id)
        return comment
    
    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
    

    当我完成项目时,我将在那里链接 repo。祝你好运!

    【讨论】:

      【解决方案2】:

      可能你需要extra-link-and-actions,例如:

      from rest_framework.decorators import detail_route
      
      class ProfileView
          # Your Code Here
      
          @detail_route(methods=['GET'])
          def albums(request, pk=None):
              # Heed to change related name 'albums_set'
              qs = self.get_object().albums_set.all()
              serializer = AlbumsSerializer(qs, many=True)
              return Response(serializer.data)
      

      【讨论】:

      • 啊哈!你建议用装饰器来做这个吗?我回家后会试试的。感谢您的意见!
      猜你喜欢
      • 2020-07-22
      • 1970-01-01
      • 2017-04-19
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2020-10-07
      • 1970-01-01
      • 2013-05-06
      相关资源
      最近更新 更多