Search by

    Django REST Frameworkのチュートリアル(Tutorial 1 Serialization)をやってみた

    Django REST Frameworkの公式チュートリアル(Tutorial 1 Serialization)をやってみた時の不明点、気付きをまとめておく。

    シリアライズって何

    言語固有のデータ形式を、共通データ形式であるjsonとかに変換すること(と理解している)。こうすることで言語間、フロント、バックの間でデータのやり取りが出来るようになる。 この時、「基本的にはこんな感じでデータのやり取りしましょう」という考え方の一つがREST

    Serialization

    djangoshell
    from snippets.models import Snippet
    from snippets.serializers import SnippetSerializer
    from rest_framework.renderers import JSONRenderer
    from rest_framework.parsers import JSONParser
    
    # インスタンスの作成
    snippet = Snippet(code='foo = "bar"\n')
    snippet.save()
    
    snippet = Snippet(code='print("hello, world")\n')
    snippet.save()
    
    # シリアライザにインスタンスを与えて初期化すると、pythonのネイティブデータタイプに変換されたことを確認できる
    serializer = SnippetSerializer(snippet)
    serializer.data
    # {'id': 2, 'title': '', 'code': 'print("hello, world")\n', 'linenos': False, 'language': 'python', 'style': 'friendly'}
    
    # jsonに変換する
    content = JSONRenderer().render(serializer.data)
    content
    # b'{"id": 2, "title": "", "code": "print(\\"hello, world\\")\\n", "linenos": false, "language": "python", "style": "friendly"}'

    Deserialization

    djangoshell
    import io
    # ※ contentはjsonにシリアライズされたデータ
    stream = io.BytesIO(content)
    
    # jsonパーサーを通すと、デシリアライズされる
    # つまりこの data はpythonのネイティブデータタイプ、snippetのインスタンスと同等品
    data = JSONParser().parse(stream)
    
    # dataをシリアライザに再格納
    serializer = SnippetSerializer(data=data)
    
    # serializers.Serializerにはヴァリデータも付属している。
    serializer.is_valid()
    # True
    serializer.validated_data
    # OrderedDict([('title', ''), ('code', 'print("hello, world")\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])
    
    # save()も持っている
    serializer.save()
    

    「djnagoのフォームに似ている」ということをドキュメントでは強調している。確かに。フォームを触った経験があるので、この章は理解しやすかった。

    シリアライザは、インスタンスだけでなく、クエリセットを受け取ることが出来る。

    
    # many=True を引数に追加してあげればよい
    serializer = SnippetSerializer(Snippet.objects.all(), many=True)
    serializer.data
    # [OrderedDict([('id', 1), ('title', ''), ('code', 'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', ''), ('code', 'print("hello, world")\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', ''), ('code', 'print("hello, world")'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]

    ModelSerializer

    モデルシリアライザー使うと、Modelformみたいな感じで modelからシリアライザを簡単に生成出来る。

    デフォでシンプルなcreate()update()を持っている。

    serializers.py
    class SnippetSerializer(serializers.ModelSerializer):
        class Meta:
            model = Snippet
            fields = ['id', 'title', 'code', 'linenos', 'language', 'style']

    ViewでAPIの実装していく

    …と思ったら、この時点ではREST frameworkの機能は使いません、とのこと。 コード例も、普通にORMでQueryを流して、Json返すだけだった。

    以前、REST framework使わなくても、 from django.http import JsonResponseがあるけど、 何が便利なんだろうなと疑問だった。やはり基本的なことは、フレームワークなしでもいいてことだね。

    逆にフレームワークが必要になるタイミングについて、ヒントが書いてある。 端的に言うと、この時点ではエラーハンドリングが出来ていない。

    • 不正なjsonを送信した場合
    • ビューが処理しないメソッドを使用して要求が行われた場合

    現時点では500サーバーエラーになってしまう。 次の章では、frameworkの機能を使って、効率的にこれらについて対応していくものと思われる。

    前の記事
    次の記事

    参考