【问题标题】:Django Rest Framework add class level method to apiDjango Rest Framework 向 api 添加类级方法
【发布时间】:2013-10-01 00:45:02
【问题描述】:

我正在使用 Django Rest Framework 来创建我的 API。我正在使用@link 返回有关特定对象的信息。

class SomeClassView(viewsets.ReadOnlyModelViewSet):
   @link
   def info(self, request, pk=None):
       obj = models.SomeClass.objects.get(pk=pk)
       return Response({"info": object.info()})

 GET: /someclass/1/info

我想做的是扩展方法,以便我可以在“类级别”访问它,以便我的 api 可以接受对象列表

class SomeClassView(viewsets.ReadOnlyModelViewSet):
   @link
   def info(self, request, pk=None):
       if isinstance(s, str):
           obj = models.SomeClass.objects.get(pk=pk)
           return Response({"info": obj.info()})
       else:
           objs = models.SomeClass.objects.filter(pk__in=pk).all()
           return Response({"infos": [obj.info() for obj in objs]})

GET: /someclass/1/info
GET: /someclass/info?pk=1&pk=2&pk=3

有没有办法可以向我的 api 添加类级别的方法?还是我需要创建一个新类来处理一个 api 调用?

PS:我不介意我是否需要一个单独的方法来完成这项工作

【问题讨论】:

    标签: python django rest django-rest-framework


    【解决方案1】:

    使用@link@action 装饰器动态生成的路由被硬编码为类似于/someclass/<pk>/<methodname>/。您可以通过添加自定义路由来公开/someclass/info 端点,例如:

    class MyRouter(DefaultRouter):
        routes = [
            Route(
                url=r'^{prefix}/((?P<pk>\d+)/)?info$',
                mapping={'get': 'info'},
                name='{basename}-info',
                initkwargs={}
            )
        ] + DefaultRouter.routes
    

    那么您的info 方法可能如下所示:

    def info(self, request, pk=None):
        if pk:
            obj = SomeClass.objects.get(pk=pk)
            return Response({'info': obj.info()})
        else:
            objs = SomeClass.objects.filter(pk__in=request.GET.getlist('pk'))
            return Response({'infos': [obj.info() for obj in objs]})
    

    (请注意没有 @link 装饰器。)

    【讨论】:

    • 我害怕那个。我希望最终的解决方案能够成为课堂的一部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 2020-01-25
    • 2016-09-06
    相关资源
    最近更新 更多