【问题标题】:How can I grab the API parameter in a Django viewset?如何在 Django 视图集中获取 API 参数?
【发布时间】:2014-02-26 06:58:21
【问题描述】:

我正在构建一个 Django 应用程序,该应用程序公开一个 REST API,用户可以通过该 API 查询我的应用程序的模型。我正在按照说明here

我的路线在 mySites url.py 中如下所示:

router.register(r'myObjects', views.MyObjectsViewSet)
....
url(r'^api/', include(router.urls)),

我的序列化器如下所示:

class MyObjectSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = MyObject
    fields = ('id', 'name',)

我的视图集如下所示:

class MyObjectsViewSet(viewsets.ModelViewSet):
    queryset = MyObjects.objects.all()
    serializer_class = MyObjectSerializer

当我点击 API /api/myObjects/ 时,它会列出所有 myObject 模型。 当我点击 API /api/myObjects/60/ 时,它只给了我 id == 60 的 myObject。 到目前为止很棒!

但是,我想更改 MyObjectsViewSet() 的逻辑,以便我可以在点击 /api/myObjects/60/ 时操作/更改它返回的内容。所以我不想做 MyObjects.objects.all() 我想做一些基于 myObject ID 60 的更复杂的事情。但我该怎么做呢?在这个视图集中,我怎样才能抓住那个数字 60?它不作为参数传入。但我真的需要它!

【问题讨论】:

    标签: python django rest


    【解决方案1】:

    在您的路由器中,再注册一个网址:

    router.register(r'myObjects/(?P<id>\d+)', views.MyObjectsViewSet)
    

    在您的视图中,您可以通过以下方式获取 id:

    self.kwargs['id']
    

    参考:http://www.django-rest-framework.org/api-guide/filtering#filtering-against-the-url

    【讨论】:

    • 这看起来很有希望!正是我需要的。但是,当我在视图集中打印 self.kwargs['id'] 时,出现以下错误: name 'self' is not defined
    • 您将不得不在视图集方法中进行复杂的操作。文档显示了一个带有 get_queryset django-rest-framework.org/api-guide/… 的示例
    • 为什么投票率这么高?由于它是视图集的性质,这会创建超过 1 个新 url...
    【解决方案2】:

    我认为您可以为多个操作更新视图,例如

    class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
                            mixins.UpdateModelMixin,
                            generics.SingleObjectAPIView):
    """
    Concrete view for retrieving or updating a model instance.
    FIXME: the newest version of rest_framework has this class
    """
    
    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)
    
    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    
    def create(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
    

    请观看此tutorial,它将帮助您了解 REST 框架。

    【讨论】:

      【解决方案3】:

      我觉得cyriacthomas 是对的,但可能需要更多细节。虽然我只是不确定为什么使用self

      我相信 sn-p 看起来像:

      class MyObjectsViewSet(viewsets.ModelViewSet):
          queryset = MyObjects.objects.all()
          serializer_class = MyObjectSerializer
      
          # Inside your class, you overwrite the retrieve function
          def retrieve(self, request, *args, **kwargs):
              obj_id = kwargs['id']
      
              query = MyObjects.objects.get(obj_id)
      
              # do something with data
      
              return self.serializer_class(data=query).data
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多