Django-rest-framework nested urls with drf-nested-routers
@Artem, I use a very similar solution in my code. Here is what I did:
I have an entity called Institutions. I created a route for it, like this:
router.register(r'institutions', SecurityViews.InstitutionViewSet, base_name='institutions')
My URLS look like this:
http://127.0.0.1:8000/v1/institutions/
http://127.0.0.1:8000/v1/institutions/1/
The first URL lists all institutions, the second, is the details URL.
Now, I have people whom I want to be members of those institutions. So, for the route, on urls.py, I did this:
institutions_router = routers.NestedSimpleRouter(router, r'institutions', lookup='institution')
institutions_router.register(r'members', SecurityViews.InstitutionMemberViewSet, base_name='institution-members')
Now, I can get the members of a particular institution with the following URL:
http://127.0.0.1:8000/v1/institutions/1/members/
I also had to define the relationships, mapping the pk of the main entity to the child entity, via serializer. I wont post the whole code here, as I imagine you are familiar with the concept.
For me, the solution proposed by @Artem solved the one problem I had: returning a filtered query. It is working fine now.
I hope this will help you.
No need to override all actions, you can just override the "get_queryset()"
class NameserverViewSet(viewsets.ViewSet):
queryset = Nameserver.objects.all()
def get_queryset(self):
if self.kwargs.get('domain_pk'):
return Nameserver.objects.filter(domain=domain_pk)
else:
return super(NameserverViewSet, self).get_queryset()
Solution came from Alan, the author.
Here is how ViewSet should be implemented:
class NameserverViewSet(viewsets.ViewSet):
queryset = Nameserver.objects.all()
def list(self, request, domain_pk=None):
queryset = self.queryset.filter(domain=domain_pk)
serializer = NameserverSerializer(queryset, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None, domain_pk=None):
queryset = self.queryset.get(pk=pk, domain=domain_pk)
serializer = NameserverSerializer(queryset)
return Response(serializer.data)