DRFのGeneric viewの使い方


公式サイトを見るとGeneric viewのクラスがいくつもあって、
どれをどのように使うのか迷ったので整理しました。

参考:公式サイト

概要

いくつかクラスがあるのですが、

クラス 操作
CreateAPIView 登録(POST)
ListAPIView 一覧取得(GET)
RetrieveAPIView 取得(GET)
UpdateAPIView 更新(PUT、PATCH)
DestroyAPIView 削除(DELETE)

を押されておけば大丈夫かと。

他のクラスは、上記クラスを組み合わせたクラスになります。
HTTPのリクエスト メソッドで役割を切り替えます。
ListCreateAPIView (POST、GET) = ListAPIView + CreateAPIView
RetrieveUpdateAPIView(GET、PUT、PATCH) = RetrieveAPIView + UpdateAPIView
RetrieveDestroyAPIView(GET、DELETE) = RetrieveAPIView + RetrieveDestroyAPIView
RetrieveUpdateDestroyAPIView(GET、PUT、PATCH) = RetrieveAPIView + UpdateAPIView + DestroyAPIView

実装

ざっくり書くと、どのクラスを使う場合も、

views.py
class [適当なクラス名](generics.[上記の使いたいクラス]):
    queryset = モデル.objects.all()
    serializer_class = モデルのSerializer
urls.py
path('api/v1/books/<str:pk>/', views.[適当なクラス名].as_view(), name='detail'),

でいけます。
urls.pyの<str:pk>は、str型のプライマリーキーを、取得や更新の条件にするという意味で、
int型だったら<int:pk>になります。
プライマリーキー以外使う場合は、使いたいカラム名で、
<int:カラム名>とし、views.pyに
lookup_field = 'カラム名'
を追加します。

サンプルプログラム

views.py
from rest_framework import generics
from shop.models import Book
from .serializers import BookSerializer

class BookList(generics.ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

class BookRetrieve(generics.RetrieveAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
#    lookup_field = 'price'

class BookRetrieveUpdate(generics.RetrieveUpdateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
#    lookup_field = 'price'

class BookUpdate(generics.UpdateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    lookup_field = 'price'

class BookDestroy(generics.DestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
urls.py
from django.urls import path, include
from rest_framework import routers
from apiv1.views.model_view import BookList

from . import views

urlpatterns = [
    path('api/v1/books/', views.model_view.BookList.as_view()),
    path('api/v1/books_retrieve/<str:pk>/', views.model_view.BookRetrieve.as_view(), name='detail'),
    path('api/v1/books_retrieve_update/<str:pk>/', views.model_view.BookRetrieveUpdate.as_view(), name='detail'),
    path('api/v1/books_update/<str:price>/', views.model_view.BookUpdate.as_view(), name='detail'),
    path('api/v1/books_destory/<str:pk>/', views.model_view.BookDestroy.as_view(), name='detail'),
]