0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Django REST Framework] Serializer の 使い方 についての話

Posted at

ここではserializersの役割を詳しく見ていこう。

備考
ビュー については View の使い方についての話を参照してください。
初めて触る方は 先にビュー編を見ることをオススメします。 シリアライザ単体で使うことはまずないと思うので。
この記事の先頭に書いてあったインストールの手順とかはそちらの記事に移動しました
基本的に情報は v3.7.7 時点の 公式ドキュメント を参考にしました。 一部以下のブログも参照させてもらいました。
[Django REST Framework] Serializer の 使い方 をまとめてみた

serializerとは?

serializerはデータ の入出力を扱い、モデルへの橋渡しをするクラスです。

Serializerの特徴

・複雑な入力値をモデルに合わせてバリデーションしてレコードに伝えたり(入力)

・Model(レコード)を適切な形式にフォーマットしたり(出力)

と言った具合に、 APIの リクエスト / レスポンス に特化した機能を提供します。

serializer types

Serializerにはいくつか種類があります。

serializers.Serializer

もっとも単純なシリアライザです。

ここでは学習してきたコードをもとに話を進めていきます。

models.py
class Account(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    fb_id = models.CharField(max_length=30, unique=True)
    ig_id = models.CharField(max_length=30, unique=True)

    def __str__(self):
        return str(self.id)

これに対応したシリアライザを以下のように定義しています。

serializers.py
class AccountSerializer(serializers.ModelSerializer):
    fb_code = serializers.CharField(required=False, write_only=True)
    ig_code = serializers.CharField(required=False, write_only=True)
    def create(self, validated_data):
        fb_code = validated_data.get("fb_code")
        ig_code = validated_data.get("ig_code")
        if fb_code:
            return fb_code
        elif ig_code:
            return ig_code

ここに書いてあることは単純で、フィールドと保存時の動作がメソッドとして定義されています。フィールドには値に対応した型を記述する。

実際にデシリアライズしていきます。デシリアライズとは入力データをもとに何らかのオブジェクトを作成することです。

注意

デシリアライズでは入力値は辞書に準ずる方でなくてはいけません。

まず、data引数に入力データを与えて、is_validメソッドをコールします。

>>>from core.models import Account
>>>from core.serializers import AccountSerializer
>>>serializer = AccountSerializer(data={'fb_code':'1234', 'ig_code': '5678'})
>>>serializer.is_valid()
>>>Out[7]: True
>>>serializer.validated_data
>>>Out[8]: OrderedDict([('fb_code', '1234'), ('ig_code', '5678')])

続いて、この入力データをオブジェクトとして出力してみます。それを行うのがシリアライズインスタンスのsave()メソッドです。

続いて、この入力データをオブジェクトとして出力してみます。 それを行うのが シリアライザインスタンスの save() メソッドです。 (saveとは言っていますが、単なるSerializerでは永続化はされません)

現在はcreateメソッドしかありませんが、updateメソッドを作ることも可能です。

バリデーションについては後述しますが、シリアライザはvalidated_dataという属性を持ち、でしリアライズされたデータのうち、バリデーションを通過した値が格納されています。

バリデーションを行うためのメソッドがis_validです。よって、このメソッドを実行した後でなければvalidated_data属性を参照することはできませんし、validated_dataをもとにオブジェクトを生成するsaveメソッドも同様に呼び出すことができません。

serializers.ModelSerializer

次はserializers.ModelSerializerについてです。

おそらく、これが一番利用されることになるSerializerです。

これはModelに紐ずくfieldをSerializerのフィールドとして自動的に定義してくれるものです。

今回はUserモデル用のシリアライザを用意します。

serializers.py
from django.contrib.auth.models import User
from rest_framework import serializers
from core.models import Account

class AccountSerializer(serializers.ModelSerializer):
    fb_code = serializers.CharField(required=False, write_only=True)
    ig_code = serializers.CharField(required=False, write_only=True)
    user = UserSerializer(read_only=True)
    class Meta:
        model = Account
        fields = ['id', 'user', 'fb_token' , 'ig_token', 'fb_code', 'ig_code', 'fb_id', 'ig_id']
        read_only_fields = ['user', 'fb_token', 'ig_token', 'fb_id', 'ig_id']

    def create(self, validated_data):
          fb_code = validated_data.get("fb_code")
          ig_code = validated_data.get("ig_code")
          if fb_code:
              return fb_code
          if ig_code:
              return ig_code

create以下のあるvalidate_data属性は入力値を変形するものです。
単純なSerializerでも使えますが、ModelSerializerで使う場合、fieldsに含まれていないと以下のようなエラーになります。

AssertionError: The field 'full_name' was declared on serializer UserSerializer, but has not been included in the 'fields' option.

先程のSerializerクラスとの違いはMetaです。Metaクラスに必須なのはmodelです。
また、write_only=TrueとはSerializerから値は入れたいけど、読み出しはしたくない場合に指定します。

Fields

次にシリアライザに指定できるフィールドについて解説します。Serializer_fieldに詳しい内容が書いてあるのでここでは重要なものだけを解説します。

Common args

read_only

・ 出力専用のフィールドか否かをBooleanで指定

write_only

required

・値の指定が必須かどうかをBooleanで指定
・デフォルトはTrueですが、Falseを指定することで入力地に該当フィールドがなくてもスルーしてくれる
・これは入力専用の設定

default

・値が省略された場合に補完する値を指定

Serializerはかなり理解する部分が多いので徐々に理解していくましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?