How to make customize detail view set using ModelViewSet?

Question:

I am new to django.
I have a model:

class Class(models.Model):
    name = models.CharField(max_length=128)
    students = models.ManyToManyField("Student")
 
    def __str__(self) -> str:
        return self.name

Now I want to create API to display the students in a particular class,the detail view, by giving the name of the class as a parameter using ModelViewClass.
Currently, I have following viewset written:

class ClassViewSet(ModelViewSet):
    serializer_class = serializers.ClassSerializer
    queryset = models.Class.objects.all()

How to do that?

Asked By: Waleed Farrukh

||

Answers:

You can use the @action(...) decorator to create a custom view.

from rest_framework.decorators import action


class ClassViewSet(ModelViewSet):
    serializer_class = serializers.ClassSerializer
    queryset = models.Class.objects.all()

    @action(detail=True, methods=['get'], url_path='students', url_name='students')
    def students(self, request, *args, **kwargs):
        class_ = self.get_object()
        students = class_.students.all()
        serializer = serializers.StudentSerializer(students, many=True)
        return Response(serializer.data)

If you are not using the DRF routers, you can specify the custom route as below,

urlpatterns = [
    path('classes/', views.ClassViewSet.as_view({'get': 'list'})),
    path('classes/<int:pk>/', views.ClassViewSet.as_view({'get': 'retrieve'})),
    path('classes/<int:pk>/students/', views.ClassViewSet.as_view({'get': 'students'})),
]

Answered By: JPG