[PYTHON] Controlling request methods in django-rest-framework

Introduction

Memo about request method control method when building API using django-rest-framework

environment

Mac 10.15.5 Python 3.8.1 Django 3.0.7 djangorestframework 3.11.0

code

I referred to the code in this article.

Controlled by inherited classes

The permission of the request method is controlled by the base class inherited by the class defined in views.py. The viewsets.ModelViewSet part of the code below. It is prepared by the imported rest_framework.

blog/views.py


import django_filters
from rest_framework import viewsets
from rest_framework import filters

from .models import User
from .models import Entry
from .serializer import UserSerializer
from .serializer import EntrySerializer


class UserViewSet(viewsets.ModelViewSet): # <-this
    queryset = User.objects.all()
    serializer_class = UserSerializer


class EntryViewSet(viewsets.ModelViewSet): # <-this
    queryset = Entry.objects.all()
    serializer_class = EntrySerializer
    filter_fields = ('author', 'status')

Contents of viewsets.ModelViewSet

It is defined in a file called viewssets.py in rest_framework. If you inherit from ModelViewSet, you can use GET, POST, PUT, and DELETE, and if you change the inherited class to ReadOnlyModelViewSet, you can control only GET.

GET, POST, PUT, DELETE available

rest_framework/viewsets.py


class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
    """
    A viewset that provides default `create()`, `retrieve()`, `update()`,
    `partial_update()`, `destroy()` and `list()` actions.
    """
    pass

Only available for GET

rest_framework/viewsets.py


class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                           mixins.ListModelMixin,
                           GenericViewSet):
    """
    A viewset that provides default `list()` and `retrieve()` actions.
    """
    pass

Specifying resources when using PUT and DELETE

When using PUT or DELETE, it is necessary to specify up to the primary key. /api/users/ -> /api/users/1/

No good


$ curl -X PUT -d name=yamada -d [email protected] localhost:8000/api/users/

OK


$ curl -X PUT -d name=yamada -d [email protected] localhost:8000/api/users/1/

This is because DjangoRestFramework needs to know which objects to update / delete. It cannot be recognized in the list view (/ api / users /). I think you will get an error like this.

{"detail":"Method \"DELETE\" not allowed."}

{"detail":"Method\"DELETE\"Is not allowed."}

reference

https://www.django-rest-framework.org/api-guide/viewsets/

https://stackoverflow.com/questions/26711975/django-drf-405-method-not-allowed-on-delete-operation/26714561#26714561

Recommended Posts

Controlling request methods in django-rest-framework
Http request in python
String object methods in Python
Methods available in the list
Methods available in set type
Dynamically call methods in Python
Dynamically define functions (methods) in Python
Get a Boolean in Flask's request