[Solved]-How to build a Django REST route that extracts multiple arguments from the URL?

6👍

Write a custom detail route and change the signature to pass in the additional kwarg you intend to use. Then, customize the url path.

from rest_framework.decorators import detail_route
from rest_framework import viewsets

class MyObjectsViewSet(viewsets.ViewSet):

    @detail_route(methods=['get'], url_path='(?P<oid>\d+)')
    def get_with_objectid(self,request,pk=None, oid=None):
        queryset = ## Do something here with oid to return a list of myObjects
        serializer = MyObjectsSerializer(queryset) ## MyObjectsSerializer not shown here.
        return Response(serializer.data,status=status.HTTP_200_OK)

Now your viewset will work with /api/MyObjects/60/59/ where pk=60 and oid=59. If the url_path was instead url_path='/thisthing/(?P(<oid>\d+)' then the viewset would register /api/MyObjects/60/thisthing/59.

👤Patti

3👍

You can have the following pattern:

url(r'^resource/(?P<clientId>[A-Za-z0-9]*)/(?P<token>[A-Za-z0-9]*)$', RestResource.as_view()),

And the RestResource class can look something like this:

class RestResource(View):
  def put(self, request, clientId, token):
    # Your code here
    return HttpResponse(json.dumps(JSON_DATA_VARIABLE), content_type = "application/json", status = 200)

  def delete(self, request, clientId, token):
    # Your code here
    return HttpResponse(json.dumps(JSON_DATA_VARIABLE), content_type = "application/json", status = 200)

It will accept “PUT” and “DELETE” requests and the parameters defined in the route will be received in the class method.

Hope it helps you,
I am available for further details if you need me.

1👍

Without using regex drf provides path with type prefix, if you don’t have strict validation for "pk" and "otherArg". So,

Step 1: In urlpatters,

path('/api/<int:id>/<otherArg>/', YourViewset.action_name, name="action_name")

Step 2: In Viewset

@action(methods=['get'],detail=True/False)

Step 3: Below @action

def action_name(self, id, otherArg):

Now use id, otherArg/s in function.
Make changes and use.

0👍

Now, "@detail_route " has been replaced by "action" after DRF 3.8.
so, can be written as follows:

@action(methods=["get"], detail=True )
def article_sort(self, request, pk):  
    otherArg = request.query_params.get('otherArg')
    ...

when detail is true, fun will get pk from url path; so now full path is "/pk/article_sort/?otherArg=60"

Leave a comment