Home > Blockchain >  How to route to specific viewset methods Django
How to route to specific viewset methods Django

Time:11-07

I've been studying the viewset and router docs for Django and I can't figure out how to set up a route to access the method on a viewset.

For example, here is my urls.py:

from rest_framework.routers import DefaultRouter
from users.views import (UserViewSet, testing)


router = DefaultRouter()    
router.register(r"users", UserViewSet, basename="users")
    
    
urlpatterns = [
    path('testing', testing)
]

And then this is my views file in my user directory

@csrf_exempt
class UserViewSet:
    def create(self):
        return JsonResponse({
            'the create endpoint'
        })


@csrf_exempt
def testing(request):
    return JsonResponse({
        "title": "My json res"
    })

Using postman, I can hit the endpoint example.com/testing and have the json response logged out. However, I try to hit example.com/users/create and I get a 404. I thought the basename propery when registering the viewset with the router would group all of the methods inside that class under that route path and then the methods would all be their own endpoint. Am I thinking about this incorrectly? Any help would be lovely as I am new to Django. I've mostly done Express and Laravel. Thanks!

CodePudding user response:

You didn't convert your router into a urlpatterns list, so you won't be able to access your viewset regardless.

To convert the router:

from rest_framework.routers import DefaultRouter
from users.views import (UserViewSet, testing)

router = DefaultRouter()    
router.register(r"users", UserViewSet, basename="users")
    
urlpatterns = [
    path('testing', testing),
    *router.urls,
]

In Django Rest Framework, a viewset's create method is executed during a POST request to a particular uri. In your case, this uri would be /users.

If you would like to add an additional method that triggers at /users/create, you will need to use the action decorator:

from rest_framework import viewsets
from rest_framework.response import JsonResponse

class UserViewSet(viewsets.ViewSet):
    @action(methods=['GET'], url_path='create')
    def my_custom_action(self):
        return JsonResponse({
            'the create endpoint'
        })

Since create is a reserved method on DRF viewsets, you will need to name the method something else (in the example, my_custom_action), and set the url_path parameter accordingly.

If you were to omit the url_path, the path would default to the name of the method, eg. /users/my_custom_action.

  • Related