Explain Codes LogoExplain Codes Logo

Disable a method in a ViewSet, django-rest-framework

python
viewsets
django-rest-framework
http-method-names
Nikita BarsukovbyNikita Barsukov·Feb 5, 2025
TLDR

Instantly disable any method like POST inside a Django REST Framework ViewSet by overriding and raising a MethodNotAllowed exception:

from rest_framework.exceptions import MethodNotAllowed class MyViewSet(viewsets.ModelViewSet): # ... def create(self, request, *args, **kwargs): # Sorry POST, not today! raise MethodNotAllowed('POST')

For conditional disabling or peculiar methods, adjust with the @action decorator:

from rest_framework.decorators import action class MyViewSet(viewsets.ModelViewSet): # ... @action(methods=['get'], detail=False) def custom_method(self, request): # GET your act together!

methods=['get'] restricts to only GET requests.

Unleashing http_method_names

Not a fan of overriding each method individually? Use http_method_names and call the shots on your allowed methods:

class MyViewSet(viewsets.ViewSet): # Define allowed HTTP methods http_method_names = ['get', 'head', 'options'] # POST me not, PUT me not, DELETE me definitely not!

This little trick even excuses unsupported actions from the Browsable API. Now that's multitasking!

Define your operations with custom mixins

With custom mixins, you can whip up a combination of operations without the extra baggage of ModelViewSet:

from rest_framework import mixins from rest_framework import viewsets # Selective operations like a boss! class CustomViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet): # Your impressive view set code here

Now, you can balance your CRUD operations like a pro and stay light on your feet!

Custom routers for precise control

Building a custom router helps you mark specific methods as no-go zones in your URL conf, ensuring they don't crash your party unwelcome:

from rest_framework.routers import SimpleRouter class CustomRouter(SimpleRouter): def get_method_map(self, viewset, method_map): # Excuse me, DELETE, this way please method_map = super().get_method_map(viewset, method_map) method_map.pop('delete', None) return method_map

This way, you guarantee that your API schema precisely mirrors the abilities your API is proud of.

Benefit gracefully from DRF 3.14.0

Don't forget to upgrade to DRF 3.14.0 for classy handling of HTTP 405 Method Not Allowed errors. Say goodbye to any disabled method in your OPTIONS request, making the powers of your API absolutely clear:

# Behold! Improved 405 management in DRF 3.14.0

This is as good as a friendly nudge to keep your Django REST Framework upgraded for security patches and an alluring array of new, fancy features.