Serializer編 -- 忙しい人のためのDjango + DjangoRestFramework
Serializerとは
dict
形式のJSONデータとPythonオブジェクトを相互変換するオブジェクト。
dict → Pythonオブジェクトの変換ではdictの値のバリデーションも行う。
Serializerを定義する
Model編で定義したDivision
モデルのSerializer
を作るときは、
-
rest_framework.serializers.Serializer
を継承してクラスを定義する。 - 変換先のPythonオブジェクトにある属性を
DivisionSerializer
クラスにも定義する。- ここでは
Division
にあるid
とname
を定義。
- ここでは
- 定義した属性
id, name
に、変換先のPythonオブジェクトDivision
の属性の型に合わせたserializers.XXXField
のインスタンスを渡す。- ここでは
id
が数値型、name
が文字列型なのでIntegerField, CharField
を渡す。 -
Field
の一覧はこちら。
- ここでは
from rest_framework import serializers
from api.models import Division
class DivisionSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField(max_length=30)
ここまでで、Division
オブジェクト → JSONの変換ができるようになる。
さらに、逆の JSON → Division
オブジェクト変換を可能にするために、Division
オブジェクトを生成するメソッドを定義する。
-
create
メソッドとupdate
メソッドを作成する。-
create
はdict形式のJSONデータを第一引数に。 -
update
は更新対象のPythonオブジェクト (ここではDivision
) を第1引数、dict形式のJSONデータを第2引数に。
-
-
create
メソッドを、JSONデータからPythonオブジェクトを生成して返すように実装する。- ここでは
Division
を生成して返す。
- ここでは
-
update
メソッドを、更新対象オブジェクトの値をJSONデータの値に書き換えて返すように実装する。- ここでは
Division
オブジェクトdivision
のname
を更新してdivision
自体を返す。
- ここでは
from rest_framework import serializers
from api.models import Division
class DivisionSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField(max_length=30)
def create(self, validated_data: dict):
""".save()を既存のDivisionを引数に**渡さず**呼ぶ時に使う"""
division = Division(**validated_data)
division.save()
return division
def update(self, division, validated_data: dict):
""".save()を既存のDivisionを引数に**渡して**呼ぶ時に使う"""
division.name = validated_data.get("name", division.name)
division.save()
return division
create
とupdate
には追加でなにか操作を加えても良い。ここでは生成/更新したDivision
をDBに保存している。
JSON → Pythonオブジェクト変換
dict
形式のJSONデータからPythonオブジェクトを生成するには、まず定義したSerializerインスタンスをJSONデータを渡して生成し、
json_data = {"id": 3, "name": "Development"}
serializer = DivisionModelSerializer(data=json_data)
バリデーションのために.is_valid()
を呼び、
serializer.is_valid() # json_dataの値や型が間違っているとFalseになる。
.save()
メソッドを呼ぶ。
division: Division = serializer.save()
バリデーション前にsave
は呼べないので、必ず最初に.is_valid
を呼び出す。
json_data
の値やその型が間違っていると、.is_valid
はFalseとなり、.save
は呼べない。
Pythonオブジェクト → JSON変換
Pythonオブジェクトdivision: Division
からdict
形式のJSONデータを生成するには、Pythonオブジェクトを渡してSerializerインスタンスを生成し、.data
にアクセスする。
s = DivisionModelSerializer(division)
json_data: dict = s.data
ModelSerializer
Modelオブジェクト <-> JSON変換を簡単に書ける
SerializerオブジェクトはDjangoのModel
クラスを変換するために定義されることが多いので、Model
クラス専用のクラスModelSerializer
が用意されている。これを使うと、最初に定義したDivisionSerializer
は以下のように簡単に定義できる。
class DivisionModelSerializer(serializers.ModelSerializer):
class Meta:
model = Division
fields = ["id", "name"]
Metaクラスのmodel
に変換先のオブジェクト、fields
にSerializer
で変換したいモデルの属性名を指定する。
これだけで、DivisionSerializer
と全く同じ動きをする。
Discussion