Skip to content
Advertisement

how to reverse the URL of a ViewSet’s custom action in django restframework

I have defined a custom action for a ViewSet

from rest_framework import viewsets

class UserViewSet(viewsets.ModelViewSet):
    @action(methods=['get'], detail=False, permission_classes=[permissions.AllowAny]) 
    def gender(self, request):
        ....

And the viewset is registered to url in the conventional way

from django.conf.urls import url, include                                          

from rest_framework import routers                                                 
from api import views                                                              


router = routers.DefaultRouter()                                                   
router.register(r'users', views.UserViewSet, base_name='myuser')                   

urlpatterns = [                                                                    
    url(r'^', include(router.urls)),                                               
]   

The URL /api/users/gender/ works. But I don’t know how to get it using reverse in unit test. (I can surely hard code this URL, but it’ll be nice to get it from code)

According to the django documentation, the following code should work

reverse('admin:app_list', kwargs={'app_label': 'auth'})
# '/admin/auth/'

But I tried the following and they don’t work

reverse('myuser-list', kwargs={'app_label':'gender'})
# errors out
reverse('myuser-list', args=('gender',))
# '/api/users.gender'

In the django-restframework documentation, there is a function called reverse_action. However, my attempts didn’t work

from api.views import UserViewSet
a = UserViewSet()
a.reverse_action('gender') # error out
from django.http import HttpRequest
req = HttpRequest()
req.method = 'GET'
a.reverse_action('gender', request=req)  # still error out

What is the proper way to reverse the URL of that action?

Advertisement

Answer

You can use reverse just add to viewset’s basename action:

reverse('myuser-gender') 

See related part of docs.

Advertisement