Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django rest framework: query parameters in detail_route

I have following ViewSet:

class BookViewSet(DefaultsMixin, viewsets.ModelViewSet):
   queryset = Book.objects.all()
   serializer_class = BookSerializer

   @detail_route()
   def chapter(self, request,pk=None):
       queryset = Chapter.objects.filter(book__pk=pk)
       serializer = ChpaterSerializer(queryset,
                       context={'request':request},
                       many=True)
       return Response(serializer.data)

So the url "/book/{id}/chapter" is valid. But I don't know how I can config the ViewSet to have a url like "/book/{id}/chapter/{id}". Maybe answer is using lookup_field or lookup_url_kwarg but I can not find usage them in the detail_route case.

like image 674
mrbf Avatar asked Nov 25 '15 05:11

mrbf


2 Answers

you can do this adding url_path in the detail_route like:

@detail_route(url_name='chapter', url_path='chapter/(?P<chapter_id>[0-9]+)')
def chapter(self, request, pk=None, chapter_id=None):
   queryset = Chapter.objects.filter(book__pk=pk)
   serializer = ChpaterSerializer(queryset,
                   context={'request':request},
                   many=True)
   return Response(serializer.data)

Note that the name of the url in the default router defaults to the url_path argument if it is provided. So the view name would inlcude the query parameter string. By specifying the url_name argument, you can simplify that. I would recommend to use the method name there, which is the default if url_path is not specified. With that, you can reverse the url with

reverse('book-chapter', kwargs={'pk': 1, 'chapter_id': 4})
like image 86
Anush Devendra Avatar answered Oct 19 '22 04:10

Anush Devendra


  1. For endpoint url as: (using Django REST ViewSets)

{mysite}/users/{pk}/password/{id}

for this to work in my viewsets i did:

class UsersViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer


@detail_route(url_path='password')
def password(self, request,pk=None):
    return HttpResponse("Wow! It Works")

from above you can retrieve id from url via pk variable.

  1. For EndPoint Url as

    {mysite}/users/{pk}/password/{number}

Change the above password method to

@detail_route(url_path='password/(?P<number>[0-9]+)')
def password(self, request,pk=None, number=None):
    return HttpResponse("Wow! It Again Works")
like image 43
Deepak Sharma Avatar answered Oct 19 '22 02:10

Deepak Sharma