ViewSets have automatic methods to list, retrieve, create, update, delete, …
I would like to disable some of those, and the solution I came up with is probably not a good one, since
OPTIONS still states those as allowed.
Any idea on how to do this the right way?
class SampleViewSet(viewsets.ModelViewSet): queryset = api_models.Sample.objects.all() serializer_class = api_serializers.SampleSerializer def list(self, request): return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED) def create(self, request): return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
The definition of
class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet)
So rather than extending
ModelViewSet, why not just use whatever you need? So for example:
from rest_framework import viewsets, mixins class SampleViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet): ...
With this approach, the router should only generate routes for the included methods.
You could keep using
viewsets.ModelViewSet and define
http_method_names on your ViewSet.
class SampleViewSet(viewsets.ModelViewSet): queryset = api_models.Sample.objects.all() serializer_class = api_serializers.SampleSerializer http_method_names = ['get', 'post', 'head']
Once you add
http_method_names, you will not be able to do
If you want
put but don’t want
patch, you can keep
http_method_names = ['get', 'post', 'head', 'put']
Internally, DRF Views extend from Django CBV. Django CBV has an attribute called http_method_names. So you can use http_method_names with DRF views too.
If you are trying to disable the PUT method from a DRF viewset, you can create a custom router:
from rest_framework.routers import DefaultRouter class NoPutRouter(DefaultRouter): """ Router class that disables the PUT method. """ def get_method_map(self, viewset, method_map): bound_methods = super().get_method_map(viewset, method_map) if 'put' in bound_methods.keys(): del bound_methods['put'] return bound_methods
By disabling the method at the router, your api schema documentation will be correct.