1

I am using Django Rest Framework to create my API. I am using @link to return information about a particular object.

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

What I would like to do is extend the method so I can access it at the "class level" so that my api could accept a list of objects

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

Is there a way I can add a class level method to my api? Or will I need to create a new class to handle the one api call?

PS: I don't mind if I need to have a separate method to make this work

1 Answer 1

3

The dynamically generated routes using the @link or @action decorators are hard-coded to look like /someclass/<pk>/<methodname>/. You can expose a /someclass/info endpoint by adding a custom route, e.g.:

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

Then your info method might look like this:

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]})

(Note the absence of the @link decorator.)

Sign up to request clarification or add additional context in comments.

1 Comment

I was afraid of that. I would have liked the final solution to have been part of the class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.