猫でもわかるWeb開発・プログラミング

本業エンジニアリングマネージャー。副業Webエンジニア。Web開発のヒントや、副業、日常生活のことを書きます。

Django REST framework Serializers

f:id:yoshiki_utakata:20210221170223p:plain

www.django-rest-framework.org

Serializers

Serializers は、Django の QuerySet や、モデルのインスタンスを、(dictのような)Pythonのネイティブなインスタンスに変換するライブラリです。Python のネイティブインスタンスに変換することで、そこから簡単に JSON や XML に変換できるようになります。 Serializers には、シリアライズだけでなく、デシリアライズの機能もあります。つなり、さまざまなインスタンスを、model や QuerySet に変換することもできます。

Django REST framewrok の serializers は、Django の Form や Modelform クラスと似ています。Serializer クラスを使うことで、さまざまな形式のレスポンスを返すことができます。例えば、 ModelSerializer では、Django の model や QuerySet をシリアライズするために使えます。

Declaring Serializers(シリアライザを定義する)

まずは、簡単なオブジェクトを作ってみます。

from datetime import datetime

class Comment:
    def __init__(self, email, content, created=None):
        self.email = email
        self.content = content
        self.created = created or datetime.now()

comment = Comment(email='leila@example.com', content='foo bar')

この Comment オブジェクトをシリアライズするためのシリアライザを定義します。

シリアライザは、Django の form の定義と非常に似ています。

from rest_framework import serializers

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

Serializing object(シリアライズする)

では、 CommentSerializer を使って、 Comment オブジェクトや、 Comment オブジェクトのリストをシリアライズしてみます。やはり、使い方は Form クラスに似ています。

serializer = CommentSerializer(comment)
serializer.data
# {'email': 'leila@example.com', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'}

これだと、まだ Python ネイティブの型に変換しただけなので、これを json に変換してみます。

from rest_framework.renderers import JSONRenderer

json = JSONRenderer().render(serializer.data)
json
# b'{"email":"leila@example.com","content":"foo bar","created":"2016-01-27T15:17:10.375877"}'

Deserializing objects(デシリアライズする)

同様に、デシリアライズもできます。まず、json から、Pythonのネイティブ型に変換します。

import io
from rest_framework.parsers import JSONParser

stream = io.BytesIO(json)
data = JSONParser().parse(stream)

それから、シリアライザクラスを使って、バリデーションされたデータに変換します。

serializer = CommentSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# {'content': 'foo bar', 'email': 'leila@example.com', 'created': datetime.datetime(2012, 08, 22, 16, 20, 09, 822243)}