[DRF] Generic Viewsの使い方
以前、APIViewを継承してgetやpostメソッドの実装について確認しました。
今回はGeneric Viewsを継承して各メソッドの動作を確認してみたいと思います。
Generic Viewsには一般的なGET/POST/PUT/DELETEの機能が実装されているため、これらを継承することで自分でメソッドの実装を書く必要がなくなります。
APIがどのメソッドを許可するのかによって継承するクラスが異なります。
それぞれの動作を確認していきます。
目次
Model, Serializerの準備
Viewを記述する前に、ModelとSerializerを作成します。
ModelSerializerについては以前の記事でViewへの記述方法などを説明しました。
Generic ViewsでもModelSerializerを使用できるので、今回もこちらを作成して使ってみます。
まずModelを作成します。
今回も本のタイトルと著者を記録するBookモデルを使用します。
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=50)
author = models.CharField(max_length=20)
def __str__(self):
return self.title
このBookモデルに対するModelSerializerは下記になります。
from rest_framework import serializers
from .models import Book
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['id', 'title', 'author']
ListAPIView
まずはListAPIViewを継承します。
ListAPIViewはGETメソッドをもつクラスで、データの一覧を返します。
Bookモデルの一覧を返すViewを作成します。
Generic Viewsを継承するためにrest_framwork.genericsをimportします。
from rest_framework import generics
from .models import Book
from .serializers import BookModelSerializer
class BookListView(generics.ListAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
上記の通り、querysetとserializer_classに値を設定しています。
querysetには、Viewが返すオブジェクトを設定します。
今回はBookモデルの全データを返すので、Book.objects.all()を設定しています。
querysetに値を設定する方法として、get_queryset()をオーバーライドする方法もあります。
例えば、全データを返すのではなく、渡されたリクエストパラメータに応じてデータをフィルターする場合などに、get_queryset()をオーバーライドします。
def get_queryset(self):
return TargetRecord.objects.filter(author=self.request.GET.get('author'))
serializer_classにはSerializerを設定します。
この設定をすることでSerializerがバリデーションとデシリアライズを行ってくれます。
querysetと同様に、get_serializer_class()をオーバーライドすることでカスタマイズすることも可能です。
それでは、URLを設定してブラウザで動作を確認します。
urlpatterns = [
path('list/', BookListView.as_view()),
]
Bookモデルの全データが表示されることを確認できました。
複雑なフィルターなどがなければ、他のViewも同じようにquerysetとserializer_classを指定するだけで使うことができます。
以降、他のViewについても簡単に動作を見ていきます。
RetrieveAPIView
RetrieveAPIViewは、指定したプライマリーキーのデータに対してGETメソッドを呼び出すViewです。
class BookView(generics.RetrieveAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
URLは下記のようにプライマリーキーを指定します。
path('list/<int:pk>/', BookView().as_view()),
ブラウザでid=2のデータを呼び出すと、下記のようになります。
CreateAPIView
POSTメソッドを持つViewです。
実装は下記のようになります。
class BookCreateView(generics.CreateAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
ブラウザでの表示は下記になります。
GETメソッドが許可されていないので既存データは確認できませんが、新規データを登録できるようになっています。
APIViewを継承してpostメソッドをオーバーライドしていた時との違いは、POSTするデータをJSON形式で記述する必要がなく、それぞれのカラムの値を入力するフィールドが用意されていることです。
下記のデータをPOSTしてみます。
201のステータスコードが返り、登録に成功したことが確認できました。
/listにアクセスし、全データを確認してみます。
先ほど登録したid=8のデータが表示されることを確認できました。
UpdateAPIView
PUT/PATCHメソッドを持つViewです。
実装は下記になります。
class BookUpdateView(generics.UpdateAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
ブラウザでid=8のデータにアクセスしてみます。
POSTと同じようにデータを入力できるフォームが用意されています。
下記のようにデータを書き換えてみます。
データの更新を確認できました。
/listにアクセスし、全データを確認してみます。
id=8のデータが更新されていることを確認できました。
DestroyAPIView
DELETEメソッドを持つViewです。
実装は下記になります。
class BookDeleteView(generics.DestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
ブラウザで先ほど作成したid=8のデータにアクセスしてみます。
この時点ではまだDELETEメソッドが実行されていないので、DELETEボタンを押してメソッドを呼び出します。
ステータスコード204が返り、削除に成功しました。
/listにアクセスし、データ一覧を確認してみます。
id=8のデータが表示されないことを確認できました。
ListCreateAPIView
ここからは複数のメソッドを持つViewについて確認していきます。
まずはGET/POSTメソッドを持つListCreateAPIViewです。
実装はこれまでのViewと同様です。
class BookGetPostView(generics.ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
ブラウザで確認します。
全データとPOSTするフォームが表示されました。
もう一度同じデータを登録してみます。
POSTに成功し、データの登録ができました。
GETボタンを押してみます。
登録したid=9のデータが表示されました。
RetrieveUpdateAPIView
RetrieveUpdateAPIViewはGET/PUTメソッドを持つViewです。
ブラウザでの動作についてはこれまでと同じですので、詳細は省略します。
実装
class BookGetPutView(generics.RetrieveUpdateAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
ブラウザ
RetrieveDestroyAPIView
RetrieveDestroyAPIViewはGET/DELETEメソッドを持つViewです。
実装
class BookGetDeleteView(generics.RetrieveDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
ブラウザ
RetrieveUpdateDestroyAPIView
RetrieveUpdateDestroyAPIViewは、GET/PUT/PATCH/DELETEメソッドを持つViewです。
実装
class BookGetPutDeleteView(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
ブラウザ
まとめ
全てのGeneric Viewsについて動作を確認してみました。
許可するメソッドに応じて適切にこれらのViewクラスを使い分けていきたいと思います。