I.Z.
I.Z.

Reputation: 197

Django rest framework. Setting up dynamic routes

I am setting up an API for a blog. I configured the output of comments for the post Here is a portion of my views.py with @action:

urls.py

router = DefaultRouter()
router.register('api/posts', APIPost)

urlpatterns = [
    path('', include(router.urls)),
]

views.py

...
    @action(methods=['get'], detail=True)
    def comments(self, request, pk=None):
        if request.method == 'GET':
            queryset = Comment.objects.filter(post__id=pk)
            serializer = CommentSerializer(queryset, many=True)
            return Response(serializer.data)
        return Response(status=status.HTTP_403_FORBIDDEN)

Now I can get all comments on a post at.

http://127.0.0.1:8000/api/posts/{post_pk}/comments/

The problem is that I just can't figure out how to get a separate comment at

http://127.0.0.1:8000/api/posts/{post_pk}/comments/{comment_pk}

I keep getting '404 Not Found' error

Upvotes: 0

Views: 992

Answers (2)

eshaan7
eshaan7

Reputation: 1068

You should create another CommentViewSet. (docs)

views.py

from rest_framework import viewsets

class CommentViewSet(viewsets.ModelViewSet):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer

urls.py

from .views import CommentViewSet

router = DefaultRouter()
router.register("api/posts", APIPost)
router.register("api/comments", CommentViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

and then you can retrieve by making a request to http://127.0.0.1:8000/api/comments/{pk}.


also, in your code,

  1. @action(methods=['get'], detail=True) it should be @action(methods=['get'], detail=False) instead because the comments action is to retrieve list of all comments. detail=True is for returning a single object.
  2. You don't need to manually check for the if request.method == 'GET' as DRF is already doing that internally because you already specified methods=["get"].

Upvotes: 1

Faisal Nazik
Faisal Nazik

Reputation: 2893

You should define URL Path or Route to a certain Address for the comments to load . Like you defined the APIPost model ...comment url route should be like below

router.register(r"comments", comments)

Upvotes: 0

Related Questions