0

I have this viewset with a custom action added

@permission_classes([IsStaffUser])
class MacroViewSet(viewsets.ModelViewSet):
    queryset = Macro.objects.all()
    serializer_class = MacroSerializer
    http_method_names = ['get', 'post', 'patch', 'head', 'delete']

    @action(methods=['post'], detail=True, url_name='add-student')
    def add_student(self, request, pk=None):
        pass

Registered in urls.py as

# application namespace
app_name = 'appname'

router = routers.DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
router.register(r'students', StudentViewSet)
router.register(r'macro', MacroViewSet, basename='macro')

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

Now, I'm trying to test my custom action. Of course I need its url. Following the drf guide, I've kwnow of the existence of reverse_action method. In my test case, I use that method as following

self.url = MacroViewSet().reverse_action('add-student', args=['1'])

Unfortunately, I keep getting this error

>       self.url = MacroViewSet().reverse_action('add-student', args=['1'])
E       AttributeError: 'MacroViewSet' object has no attribute 'basename'
dc_Bita98
  • 851
  • 2
  • 17
  • 35
  • when you try to access directly it works? .. what is the result of `MacroViewSet().add_student.url_name`? – cabesuon May 16 '20 at 21:23
  • @cabesuon `MacroViewSet().add_student.url_name` --> `add-student` – dc_Bita98 May 16 '20 at 21:35
  • OK, can access directly to the endpoint? – cabesuon May 16 '20 at 21:46
  • @cabesuon not sure what you asked. I think the endpoint is ok, because `reverse('errepiuapp:macro-add-student', {'1'})` works fine. On the contrary, no way **reverse_action** works – dc_Bita98 May 16 '20 at 21:48
  • I was just checking that the endpoint was working, and to know the full path .. BTW, it's weird, `reverse_action` is just a wrapper of `reverse` ... One more question, if you try `reverse_action` with `user` and `student` it works? – cabesuon May 17 '20 at 02:31
  • @cabesuon `UserViewSet().reverse_action('list')` gives the exactly same error: no attribute **basename**, although I configure it in the router. I check with the debugger and when I call the api's view with a client, the basename attribute is set properly. This led me to a thought: maybe I need to call `as_view()` on my ViewSets in order to set *basename* and *request* attribute. But it doesn't work anyway – dc_Bita98 May 17 '20 at 09:47

0 Answers0