9

I am building nested API with drf-nested-routers package.

However /domains/1/nameservers/ gives me all nameservers I have, not only one related to domain#1

I think the problem is that I use default tutorial NameServerViewSet implementation

class NameserverViewSet(viewsets.ModelViewSet):
    queryset = Nameserver.objects.all()
    serializer_class = NameserverSerializer

Please help me code it right way.

Below are examples from drf-nested-routers github page.

drf-nested-routers provides nested router that generates url patterns below

\domain\ <- Domains list \domain{pk}\ <- One domain, from {pk]

\domain{domain_pk}\nameservers\ <- Nameservers of domain from

{domain_pk} \domain{domain_pk}\nameservers\ {pk}\ <- Specific nameserver from {pk}, of domain from {domain_pk}

Here is an example:

# urls.py
from rest_framework_nested import routers
from views import DomainViewSet, NameserverViewSet
(...)

router = routers.SimpleRouter()
router.register(r'domains', DomainViewSet)

domains_router = routers.NestedSimpleRouter(router, r'domains', lookup='domain')
domains_router.register(r'nameservers', NameserverViewSet)

urlpatterns = patterns('',
    url(r'^', include(router.urls)),
    url(r'^', include(domains_router.urls)),
)

3 Answers 3

11

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)
Sign up to request clarification or add additional context in comments.

1 Comment

Do you have a clue what is misconfigured on my project?
5

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()

1 Comment

domain_pk is not defined here it seems
2

@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.

Comments

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.