26

I wish to implement my new API with a nested resource.

Example: /api/users/:user_id/posts/

Will evaluate to all of the posts for a specific user. I haven't seen an working example for this use case, maybe this isn't the right way for implementing rest API?

3
  • Where are you stuck? This is fairly straight forward, assuming you already setup OAUTH2. Commented Oct 20, 2014 at 7:29
  • How my serlizers will be? which related fields to choose? Commented Oct 20, 2014 at 7:57
  • github.com/alanjds/drf-nested-routers Commented Jun 13, 2019 at 12:56

3 Answers 3

31

As commented by Danilo, the @link decorator got removed in favor of @list_route and @detail_route decorators.

Update: @detail_route & @list_route got deprecated in favor of @action.

Here's the alternate solutions:

Solution 1:

@detail_route()
def posts(self, request, pk=None):
    owner = self.get_object()
    posts = Post.objects.filter(owner=owner)

    context = {
        'request': request
    }

    post_serializer = PostSerializer(posts, many=True, context=context)
    return Response(post_serializer.data)

Solution 2:

Try drf-nested-routers. Haven't tried this out yet, but looks promising, many are already using it. Looks like an advanced version of what we are already trying to achieve.

Hope this helps.

Sign up to request clarification or add additional context in comments.

2 Comments

@PranjalMittal use @detail_route(methods=['post']). Checkout the doc here
With action decorator: @action(detail=False, methods=["GET"])
5

To map /api/users/:user_id/posts/ you can decorate a posts method inside your ViewSet with @link()

from rest_framework.decorators import link
from rest_framework.response import Response


class UserViewSet(viewsets.ModelViewSet):
    model = User
    serializer_class = UserSerializer
    
    # Your regular ModelViewSet things here

    # Add a decorated method like this
    @link()
    def posts(self, request, pk):
        # pk is the user_id in your example
            
        posts = Post.objects.filter(owner=pk)    
        
        # Or, you can also do a related objects query, something like:
        # user = self.get_object(pk)
        # posts = user.post_set.all()

        # Then just serialize and return it!
        serializer = PostSerializer(posts)
        return Response(serializer.data)

    

1 Comment

Link decorator got removed in favor of listed_route and detail_rout decorators: github.com/tomchristie/django-rest-framework/commit/…
2

As commented by Danilo Cabello earlier you would use @detail_route or @list_route instead of @link(). Please read the documentation for "Routers", section "Extra link and actions" and "ViewSets", section "Marking extra actions for routing" for detailed explanations.

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.