この記事では、DjangoRESTframeworkのシリアライザとビューの基礎知識と使い方について紹介します。
Django利用のアプリケーションと、DjangoRESTframework(Django含む)利用のアプリケーションの大きさ違いは、API接続を利用するかどうかです。
DjangoRESTframeworkを利用する際のAPI接続の方法の指定で重要になるのは、シリアライザクラスの利用と、ビュークラスのコーディングです。
今回は、DjangoRESTframework利用時のシリアライザクラスと、ビュークラスの特徴と基礎的なコーディングの方法について解説します。
◆動作検証環境
・python:3.7.5
・Django:3.1.2
・DjangoRESTframework: 3.12.1
ご自身のローカル環境で試す場合は、こちらの記事を参考に環境を準備してください。
この記事では、DjangoRESTframeworkのインストール、初期設定と最低限の動作確認の方法を紹介します。 ◆動作検証環境・ローカル環境:mac Catalina・python:3.7.5・Dj[…]
シリアライザ(serializer)の設定
シリアライザクラスは、serializers.pyに定義する方法が一般的です。
djangoのプロジェクト内で新規のアプリケーションを作る際のpython3 manage.py startapp appname には含まれないファイルのため、自分で追加します。
今回の記事で利用するプロジェクトでは、API用のアプリケーションとして、apiアプリケーションを作成しています。
serializers.pyと、通常のdjangoプロジェクト同様urls.pyも追加しています。
シリアライザクラス(serializer class)の条件
シリアライザクラスの条件は、ModelSerializer ,listSerializer ,Serializer のいずれかを継承する必要があります。
各シリアライザの特徴は以下のとおりです。
ModelSerializer:
Modelクラスで定義しているフィールドをJSON文字列と変換するシリアライザとして利用する。
listSerializer:
複数のModelリソースを利用する。
Serializer:
Modelを利用せず自分で定義した形でJSON文字列と変換するシリアライザとして利用する。
利用しやすい形は、すでに作成しているModelクラスと利用するModelSerializerを継承する方法です。
今回は、こちらの形での使用方法を紹介します。
ModelSerializerを継承してシリアライザクラスを作る時は、Modelが必要となりますので、まずこちらを作ります。
api/models.py
1 2 3 4 5 6 7 8 9 10 11 12 13 | from django.db import models class Weather(models.Model): date = models.DateTimeField(verbose_name='日時', auto_now_add=False) place = models.CharField(verbose_name='場所', max_length=20) weather = models.CharField(verbose_name='天気', max_length=20) temp = models.IntegerField(verbose_name='温度') class Meta: verbose_name_plural = 'Weather' |
modelクラスのWeatherクラスを利用するWeatherSerializerを、serializers.pyに作ります。
api/serializers.py
1 2 3 4 5 6 7 8 9 10 | from rest_framework import serializers from .models import Weather class WeatherSerializer(serializers.ModelSerializer): class Meta: model = Weather fields = ('date', 'place', 'weather', 'temp') |
class Meta:内で利用するModelとfieldsを指定しています。
もちろん、fieldsは指定しているModelに含まれているものとします。
指定の方法は、field名をリストまたはタプルで使用するか、__all__ とする事で全てのfieldを指定する事ができます。
exclude = ['date'] とする事で使用しないfieldを指定する方法もあります。1 2 3 4 5 | fields = ('date', 'place', 'weather', 'temp') fields = '__all__' exclude = 'date' |
なお、Serializerを継承して作るSerializeクラスの場合は下記の方法でfieldをSerializeクラス内に定義します。
よく利用するfieldの指定の方法は以下のとおりです。
Serializeクラスで指定方法 | Modelクラスで指定方法 |
rest_framework.fields.BooleanField | django.db.models.BooleanField |
rest_framework.fields.CharField | django.db.models.CharField |
rest_framework.fields.CharField | django.db.models.TextField |
rest_framework.fields.IntegerField | django.db.models.IntegerFiel |
rest_framework.fields.FloatField | django.db.models.FloatField |
rest_framework.fields.DateField | django.db.models.DateField |
使用例は以下のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from rest_framework import serializers class WeatherSerializer(serializers.Serializer): date = serializers.DateField() place = serializers.CharField() weather = serializers.CharField() temp = serializers.IntegerField() """ fieldsを利用する処理を行う """ |
ビュー(View)の設定
通常のDjangoのプロジェクトでも、Viewクラスは利用されますが、DjangoRESTframeworkの場合は、JSON形式 のリクエストを受け取り、JSON形式のレスポンスを返す役割を行います。
DjangoRESTframeworkでViewクラスを作る時は、views.APIView , generics.APIView , viewsets.ModelViewSet のいずれかを継承します。
各クラスの特徴は以下のとおりです。
views.APIView
APIのリクエストは、GET・POST・PUT・PATCH・DELETEのいずれかのHTTPメソッドとなります。
views.APIViewを継承するクラスの場合、各メソッドに対応するメソッドを自分で作る必要があります。
CreateAPIView、ModelViewSetを継承するテンプレート形式では対応できない、細かな設定にも対応できます。
generics.APIView
通常のDjangoのViewでは、一覧表示、登録、更新、削除などのいわゆるCRUDに対応するテンプレートが利用できるように、DjangoRESTframeworkでも各アクションに応じたテンプレートが用意されており、generics.CreateAPIView系を継承する事で可能となります。
CreateAPIView系には、目的ごとに種類がよく利用するものには以下のものがあります。
- 一覧(GET):ListAPIView
- 詳細(GET):RetrieveAPIView
- 登録(POST):CreateAPIView
- 更新(PUT、PATCH):UpdateAPIView
- 削除(DELETE):DestroyAPIView
他の種類についてはこちらを参考にしてください。
https://www.django-rest-framework.org/api-guide/generic-views/#listcreateapiview
Viewクラスは、queryset と、serializer_class を指定する必要があり、対象のModelとserializerを指定します。
ListAPIViewを継承したViewクラスの例です。
1 2 3 4 5 6 7 8 9 10 11 | from rest_framework import generics from .models import Weather from .serializers import WeatherSerializer class WeatherAPIView(generics.ListAPIView): queryset = Weather.objects.all() serializer_class = WeatherSerializer |
viewsets.ModelViewSet
数種類のgenerics.APIViewを利用する事で、CRUDの動きに対応する事も可能ですが、viewsets.ModelViewSetを継承する事でより簡単に対応する事ができます。
ModelViewSet系には2種類クラスがあり、対応するHTTPメソッドは以下のとおりです。
一覧(GET) | 詳細(GET) | 登録(POST) | 更新(PUT) | 一部更新(PATCH) | 削除(DELETE) | |
ModelViewSet | ○ | ○ | ○ | ○ | ○ | ○ |
ReadOnlyModelViewSet | ○ | ○ |
このように、ModelViewSetを利用すると、ひとつのクラスで(エンドポイントの切り替えて)CRUDの動き全てに対応できます。
ReadOnlyModelViewSetは、GETのみのメソッドの利用が可能となっており、こちらもログインをしないでも閲覧可能な情報の表示の時等に重宝します。
ModelViewSetを継承したViewクラスの例です。
1 2 3 4 5 6 7 8 9 10 11 | from rest_framework import viewsets from .models import Weather from .serializers import WeatherSerializer class WeatherAPIView(viewsets.ModelViewSet): queryset = Weather.objects.all() serializer_class = WeatherSerializer |
ルーティング(urls.py)の設定
views.APIView、generics.APIViewを継承する場合
views.APIView、generics.APIViewのルーティングの場合は、Django同様のルーティングの方法を取ります。
PKの指定が必要な場合(削除、更新)は、<pk>で指定します。
以下、ListAPIView、DestroyAPIViewを継承したViewクラスのルーティングの例です。
api/views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from rest_framework import generics from .models import Weather from .serializers import WeatherSerializer class WeatherAPIView(generics.ListAPIView): queryset = Weather.objects.all() serializer_class = WeatherSerializer class WeatherDeleteAPIView(generics.DestroyAPIView): queryset = Weather.objects.all() serializer_class = WeatherSerializer |
api/urls.py
1 2 3 4 5 6 7 8 9 | from django.urls import path from .views import WeatherAPIView, WeatherDeleteAPIView urlpatterns = [ path('list/', WeatherAPIView.as_view()), path('delete/<pk>/', WeatherDeleteAPIView.as_view()), ] |
viewsets.ModelViewSetを継承する場合
ModelViewSetを継承するViewクラスの場合、ルーティングも簡素に記述する事が可能です。
下記のように書くことで、/api/weather/ or /api/weather/<pk>/ と、HTTPメソッドの種類によって、CRUDのアクションに対応します。
api/urls.py
1 2 3 4 5 6 7 8 9 10 11 12 | from django.urls import path, include from rest_framework import routers from . import views router = routers.SimpleRouter() router.register('weather', views.WeatherAPIViewSet) urlpatterns = [ path('', include(router.urls)), ] |
api/views.py
1 2 3 4 5 6 7 8 9 10 11 | from rest_framework import viewsets from .models import Weather from .serializers import WeatherSerializer class WeatherAPIViewSet(viewsets.ModelViewSet): queryset = Weather.objects.all() serializer_class = WeatherSerializer |
なお、ModelViewSetを継承するViewクラスを、views.APIView、generics.APIViewを使う時の方法path('list/', WeatherAPIView.as_view()) というようにルーティングの指定をすると、サーバー立ち上げ時に下記にようなエラーが発生しまので、routers.SimpleRouter() を利用する方法にしてください。
1 2 3 4 | raise TypeError("The `actions` argument must be provided when " TypeError: The `actions` argument must be provided when calling `.as_view()` on a ViewSet. For example `.as_view({'get': 'xxxxx'})` |
サーバーを立ち上げ、/api/weather/にアクセスした際、下記のようにブラウザが表示されHTTPメソッドが選択できるようになります。
/api/weather/<pk>/にアクセスした際は下記のようにブラウザが表示されます。
以上、DjangoRESTframeworkのシリアライザとビューの基礎知識と使い方について紹介してきました。
今回紹介した内容は基本的なところのみであり、特にViewクラスは、条件をつけて検索結果を取得したり、ログイン済みのユーザーのみアクセスを可能にする事や、アクセスの回数制限などを設定する際により詳しく設定する事が多いです。
今後の記事にて他の利用方法も紹介する予定です。
参考ソース:https://www.django-rest-framework.org/