Nested resources in Django REST Framework
Solution 1
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.
Solution 2
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)
Solution 3
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.
Related videos on Youtube
Tal Peretz
Updated on June 04, 2022Comments
-
Tal Peretz almost 2 years
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?
-
Mykel over 9 yearsWhere are you stuck? This is fairly straight forward, assuming you already setup OAUTH2.
-
Tal Peretz over 9 yearsHow my serlizers will be? which related fields to choose?
-
Kermit almost 5 years
-
-
Danilo Cabello about 9 yearsLink decorator got removed in favor of listed_route and detail_rout decorators: github.com/tomchristie/django-rest-framework/commit/…
-
Ankit Popli almost 8 years@PranjalMittal use @detail_route(methods=['post']). Checkout the doc here
-
zentia almost 2 yearsWith action decorator: @action(detail=False, methods=["GET"])