I've got two models, one of a box and one of box comment:
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've set up a router to make Boxes available at /boxes/
and specific boxes available at /boxes/{id}/
using
router.register(r'boxes', feed.views.BoxViewSet)
is it possible to make comments available at /boxes/{id}/comments/
? Or should I just set up a separate route and use GET/POST parameters to refer to specific boxes?
This is typically referred to as nested routers (or nested viewsets), and it's generally not recommended in Django REST Framework. If possible, you should use a flat representation in your APIs, so
/boxes/{id}/comments
would actually be
/comments/?box={id}
This is considerably easier to implement with Django REST Framework using the built-in filtering (and maybe django-filter). It's guaranteed not to break in future versions of DRF, and it's the recommended way at the moment. The HTTP API guidelines might be a good read if you're interested why, and there's a discussion about it there as well.
Now, you can't always avoid using nested routers. I've written about it in the past, using the third-party packages that were available at the time. Since then, drf-extensions has integrated it and it contains a decent implementation of nested routers that should work for most cases.
I don't see any problems to do this (I already use it in my projects and everything is fine) - all you need is an url with box_id
kwarg. This has nothing with "nesting routers", it's just another endpoint with explicit filtering by url kwarg.
router.register(r'boxes/(?P<box_id>\d+)/comments', BoxCommentViewSet)
Then just filter out corresponding comments in get_queryset
class BoxCommentViewSet(viewsets.ModelViewSet):
def get_queryset(self):
return BoxComment.objects.filter(
box=self.kwargs['box_id']
)