Adding additional actions to view sets

You can add extra actions to view sets. Let's change our previous CourseEnrollView view into a custom view set action. Edit the api/views.py file and modify the CourseViewSet class to look as follows:

from rest_framework.decorators import detail_route

class CourseViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Course.objects.all()
serializer_class = CourseSerializer

@detail_route(methods=['post'],
authentication_classes=[BasicAuthentication],
permission_classes=[IsAuthenticated])
def enroll(self, request, *args, **kwargs):
course = self.get_object()
course.students.add(request.user)
return Response({'enrolled': True})

We add a custom enroll() method that represents an additional action for this view set. The preceding code is as follows:

  1. We use the detail_route decorator of the framework to specify that this is an action to be performed on a single object.
  2. The decorator allows us to add custom attributes for the action. We specify that only the post method is allowed for this view and set the authentication and permission classes.
  3. We use self.get_object() to retrieve the Course object.
  4. We add the current user to the students many-to-many relationship and return a custom success response.

Edit the api/urls.py file and remove the following URL, since we don't need it anymore:

path('courses/<pk>/enroll/',
views.CourseEnrollView.as_view(),
name='course_enroll'),

Then edit the api/views.py file and remove the CourseEnrollView class.

The URL to enroll in courses is now automatically generated by the router. The URL remains the same, since it's built dynamically using our action name enroll.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset