1

I have a ModelViewset in Django Rest Framework :

class UserViewset(viewsets.ModelViewSet):
    queryset = models.User
    serializer_class = serializers.User

Its router :

router = routers.DefaultRouter()
router.register(r'user', views.UserViewset)

I would like separate URLs for the create, update, list and retreive functions of this Viewset :

/user/register/            : POST (create new user)
/user/<pk>/profile         : GET (retrieve profile of user)
/user/<pk>/profile/update/ : PATCH (update profile of user)
/user/list                 : GET (get list of users)

How can this be achieved (using routers or URLs)?

Sagar Agarwal
  • 153
  • 2
  • 11
  • One way would be creating more views for each and instead of using routing then using path. ``path('/user/register/', views.register.as_view(), name='user-register')``. Then only handling POST requests in the register view. – LeOverflow Jun 10 '21 at 19:45
  • Isn't it possible to define separate URLs for the same viewset functions ? – Sagar Agarwal Jun 10 '21 at 19:49
  • Yeah, try with ``path('/user/...', views.UserViewset.as_view(), name='user-..')``. I am not sure how to utilize the actual url unless specified as a parameter: ````, but maybe that isn't necessary in any case.. – LeOverflow Jun 10 '21 at 19:56

1 Answers1

2

You can do this with something like:

from rest_framework.decorators import action


class UserViewset(viewsets.ModelViewSet):
    queryset = models.User
    serializer_class = serializers.User

    # GET: /user/register/
    @action(detail=False, url_path='register/')
    def user_register(self, request):
        ...

    # GET: /user/<pk>/profile
    @action(detail=True, methods=['get'])
    def profile(self, request, pk=None):
        ...

    # PATCH: /user/<pk>/profile/update/
    @action(detail=True, methods=['patch'], url_path='profile/update/')
    def profile_update(self, request, pk=None):
        ...

    # GET: /user/list 
    @action(detail=False, url_path='list/')
    def user_list(self, request, *args, **kwargs):
        # You can do super().list(request, *args, **kwargs) here, up to you
        ...

You can read more about this from:

https://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing https://www.django-rest-framework.org/api-guide/routers/#routing-for-extra-actions

Brian Destura
  • 11,487
  • 3
  • 18
  • 34