2

I need to capture the url params in the following url "/portal/{pk}/portalProject/{pk}"

the following url is not leading to the view function below . What is wrong here?

urls.py

router = routers.DefaultRouter()
router.register(r'movies', MoviesViewSet)
router.register(r'project', ClientViewSet)
router.register(r'portal', PortalViewSet)
router.register(r'portal/(?P<portal_pk>\d+)/portalProject/(?P<portalProject_pk>\d+)/$', PortalViewSet, 'portalProject')
router.register(r'portalProject', PortalProjectViewSet)

views.py

class PortalViewSet(viewsets.ModelViewSet):
    ...
    @detail_route(methods=['post','get'])
    def portalProject(self, request, pk=None):
        print "in here"
        if request.method == 'post':
            #some code            
            serializer = PortalProjectSerializer(data=request.data)
            if serializer.is_valid():
                print "valid"
                serializer.save()
                return Response(status=status.HTTP_200_OK)
            else:
                print serializer.errors
                return Response(status=status.HTTP_400_BAD_REQUEST)
        else:
            #some code
            return Response(status=status.HTTP_200_OK)
    ...
4
  • just for slow readers like myself: portalProject is a method inside a PortalViewSet class (which derives ViewSet). Commented Jan 25, 2016 at 9:26
  • I fail to find any example in which DefaultRouter accepts a regular expression as first parameter. I assume that you cannot...? Commented Jan 25, 2016 at 9:30
  • Yes Default router does not accept Reg EX . I was trying different things . Copied the same here . Commented Jan 25, 2016 at 9:38
  • Ok! Just in case I was unaware of some neat feature of DefaultRouter ;) Commented Jan 25, 2016 at 9:39

1 Answer 1

3

You don't actually declare a specific route in DefaultRouter. The router takes care of creating all sub urls for you. Just doing router.register(r'portal', PortalViewSet) will give you:

  • [.format]
  • {prefix}/[.format]
  • {prefix}/{methodname}/[.format] - @list_route decorated method
  • {prefix}/{lookup}/[.format]
  • {prefix}/{lookup}/{methodname}/[.format] - @detail_route decorated method

So unless you want to create a custom router, you're gonna have to change your url pattern to something like /portal/{pk}/portalProject/?id={pk}

Also, if you're requesting the portalProject by pk anyway, then there is no need for nesting the url under /portal/{pk}. The pk of portalProject is already specific enough. You already have a route for portalProject, so you would effectively be getting two ways of accessing the same data, one of them being more complicated for no good reason.

However, I believe this is what you're looking for:
https://github.com/alanjds/drf-nested-routers
or https://chibisov.github.io/drf-extensions/docs/#nested-routes

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

5 Comments

Yes I already have PortalProjectViewSet , I am looking to remove that and provide a kind the url /portal/{id}/portalProject/{id}
Does that have any practical application?
Thanks for the links . Is there any other way to do this ? I don't want to install extra package .
I don't think django-rest-framework is designed for this kind of nesting. Obviously this is possible, but it's always going to be much more work than just going with the standard. Here is another approach: gist.github.com/kevin-brown/6112838

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.