Django REST Framework add ViewSet as detail to another ViewSet

I have two models, one from the boxes and one from the comments in the box:

class BoxViewSet(viewsets.ModelViewSet): queryset = Box.objects.all() permission_classes = IsAuthenticated, serializer_class = BoxSerializer

class BoxCommentViewSet(viewsets.ModelViewSet): model = BoxComment serializer_class = CommentSerializer permission_classes = IsAuthenticated def get_queryset(self): # this should return a queryset that filters based on the # box in the route return BoxComment.objects.all()

If I configured the router to make Boxes available in /boxes/

and out of specific cells available in /boxes/{id}/

, using is   router.register(r'boxes', feed.views.BoxViewSet)


it possible to make comments in /boxes/{id}/comments/

? Or should I just set up a separate route and use GET / POST parameters to link to certain fields?

+3


source to share


2 answers


This is commonly referred to as nested routers (or nested views) and is generally not recommended in the Django REST Framework. If possible, you should use flat representation in your APIs, so

/boxes/{id}/comments

      

will actually

/comments/?box={id}

      



This is much easier to implement with the Django REST Framework using built-in filtering (and possibly django-filter ). It has ensured that it will not be broken into future versions of DRF, which is the recommended way at the moment . API API API can be a good read if you're wondering why, and there's a discussion about it .


Now you can't always avoid using nested routers. I've written in the past using third party packages that were available at the time. Since then drf-extensions has included it and contains a decent implementation of nested routers that should work in most cases.

+1


source


I don't see any problem for this (I already use it in my projects and everything is fine) - all you need is a URL with box_id

kwarg. This has nothing to do with "socket routers", it is just another endpoint with explicit kwarg url filtering.

router.register(r'boxes/(?P<box_id>\d+)/comments', BoxCommentViewSet)

      



Then just filter the relevant comments into get_queryset

class BoxCommentViewSet(viewsets.ModelViewSet):

    def get_queryset(self):
        return BoxComment.objects.filter(
            box=self.kwargs['box_id']
        )

      

+3


source







All Articles