Django REST frameworkのViewまとめ


1. Function based Views

requestを受け取りResponseを返す関数に@api_viewデコレータを使用してビューを定義する.

from rest_framework.decorators import api_view

@api_view(['GET', 'POST'])
def hello_world(request):
    if request.method == 'POST':
        return Response({"message": "Got some data!", "data": request.data})
    return Response({"message": "Hello, world!"})

@permission_classes(...)@renderer_classes(...)などのデコレータを使用することで,設定を追加することができる.

2. Class based Views

APIViewを継承したクラスによってビューを定義する.

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions
from django.contrib.auth.models import User

class ListUsers(APIView):
    authentication_classes = [authentication.TokenAuthentication]
    permission_classes = [permissions.IsAdminUser]

    def get(self, request, format=None):
        usernames = [user.username for user in User.objects.all()]
        return Response(usernames)

.get().post()などをハンドラメソッドと呼ぶ.
送られてきたリクエストは設定されたパーミッション等のチェックを通った後,ハンドラメソッドに送られる.

3. Generic Views

いくつか用意されている汎用(ジェネリック)ビューを継承したクラスによって定義する.

from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import generics
from rest_framework.permissions import IsAdminUser

# 作成と一覧取得ができるビュー
class UserList(generics.ListCreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [IsAdminUser]

汎用ビューはquerysetを設定し紐付けるため,基本的な動作をさせる場合は簡略化して書くことができる.
また,アクションメソッド(後述)等をオーバーライドして動作を拡張することもできる.

class UserList(generics.ListCreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [IsAdminUser]

    def list(self, request):# アクションメソッド
        queryset = self.get_queryset()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)

汎用ビューは共通の基底クラスGenericAPIView(後述)と基本的な動作を提供するMixin(後述)を1つまたは複数継承している.各Mixinによって提供される動作は後述.

汎用ビュー 継承しているMixin
CreateAPIView CreateModelMixin
DestroyAPIView DestroyModelMixin
ListAPIView ListModelMixin
ListCreateAPIView ListModelMixin, CreateModelMixin
RetrieveAPIView RetrieveModelMixin
RetrieveDestroyAPIView RetrieveModelMixin, DestroyModelMixin
RetrieveUpdateAPIView RetrieveModelMixin, UpdateModelMixin
RetrieveUpdateDestroyAPIView RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
UpdateAPIView UpdateModelMixin

GenericAPIView

APIViewを拡張し,よく使われる動作を追加したクラス.すべての汎用ビューの基底.

queryset.get_queryset(self)で使用するクエリセットを設定できる.
.perform_create(self, serializer).perform_update(self, serializer).perform_destroy(self, instance)でオブジェクトの保存・削除時の動作をオーバーライドできる.これらはMixinのアクションメソッドから呼び出される.

Mixin

基本的なビューの動作を行うためのアクションメソッドを提供するクラス.

Mixin アクションメソッド 動作
ListModelMixin .list() 一覧取得
CreateModelMixin .create() 作成
RetrieveModelMixin .retrieve() 取得(単体)
UpdateModelMixin .update()
.partial_update()
更新
部分更新
DestroyModelMixin .destroy() 削除

4. Viewsets

viewsets.ModelViewSet等を継承したクラスによって定義する.

from django.contrib.auth.models import User
from myapps.serializers import UserSerializer
from rest_framework import viewsets
from rest_framework.response import Response

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    queryset = User.objects.all()

ModelViewSetはすべてのMixinが一緒になったようなクラス(実際すべてのMixinを継承している)で,これだけで取得・作成・一覧取得・更新・削除ができるようになる.
ビューセットはアクションメソッドを提供する(ハンドラメソッドではない)ので,機能を拡張したい場合はアクションメソッドをオーバーライドする.

Viewsets 説明
ViewSet APIViewを継承.アクションメソッドを提供せず,使う場合は明示的にオーバーライドする必要がある.
GenericViewSet GenericAPIViewを継承.queryset等の設定ができる.明示的にアクションメソッドをオーバーライドするか,Mixinと一緒に継承する.
ModelViewSet GenericViewSetと各Mixinを継承.各種アクションメソッドを提供する.
ReadOnlyModelViewSet GenericViewSetとRetrieveModelMixin,ListModelMixinを継承.取得と一覧取得のみを提供する.

各クラスの継承関係

参考

本記事の内容及びサンプルコードは以下を参考・引用した.