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

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

Django REST framework シリアライザの種類

f:id:yoshiki_utakata:20210221170223p:plain

ModelSerializer

JSON, XML など ↔︎ Django の model の変換をするクラス。

ModelSerializer は、ほぼ Serializer クラスと同じだが、以下の点だけ異なる

  • デフォルトで model のフィールドを読み込んでくれる
  • unique_together のようなバリデーションをしてくれる
  • デフォルトで create() メソッドと update() メソッドが実装されている

使用例:

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'account_name', 'users', 'created']

デフォルトだと、model に存在する全てのフィールドがシリアライズされます。

ForeignKey のようなリレーションは PrimaryKeyRelatedField というものにマッピングされます。Reverse relationship は自動的にはマッピングされません。

どのフィールドを含めるか

fields または exclude オプションを使います。

想定外のフィルドが増えないように、fields オプションを使うことを推奨します。

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'account_name', 'users', 'created']

特別な値として、 fields'__all__' を指定することもできます。

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = '__all__'

exclude を指定することもできます。

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        exclude = ['users']

ネストされたフィールドのシリアライズ

depth を指定することができます。

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'account_name', 'users', 'created']
        depth = 1

フィールドの形式を指定する

このように、フィールドの型を自分で指定することもできます。

class AccountSerializer(serializers.ModelSerializer):
    url = serializers.CharField(source='get_absolute_url', read_only=True)
    groups = serializers.PrimaryKeyRelatedField(many=True)

    class Meta:
        model = Account

Readonly なフィールド

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'account_name', 'users', 'created']
        read_only_fields = ['account_name']

model において、 editable=False なフィールドや AutoField など、デフォルトで readonly なフィールドがある場合は、 read_only_field に追加しなくても readonly になります。

HyperlinledModelSerializer

ModelSerializer クラスと似ていますが、リレーションがハイパーリンクになります。

class AccountSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Account
        fields = ['url', 'id', 'account_name', 'users', 'created']

ListSerializer

通常 ListSerializer を直接使うことはありません。

ListSerializer の挙動をカスタマイズしたい場合にのみ使います。

例えば、

  • リスト全体のバリデーションをしたい場合、例えば、リストの中で重複を排除するなど
  • 複数オブジェクトを保存したり更新したりする場合の挙動を変えたい場合

実装例:

class CustomListSerializer(serializers.ListSerializer):
    ...

class CustomSerializer(serializers.Serializer):
    ...
    class Meta:
        list_serializer_class = CustomListSerializer

例えば、create メソッドを変更したい場合

class BookListSerializer(serializers.ListSerializer):
    def create(self, validated_data):
        books = [Book(**item) for item in validated_data]
        return Book.objects.bulk_create(books)

class BookSerializer(serializers.Serializer):
    ...
    class Meta:
        list_serializer_class = BookListSerializer

BaseSerializer

BaseSerializer を継承して、独自のシリアライザを実装することもできる。

基本的に Serializer クラスと同じだが、BaseSerializer には、 HTML のフォームを生成する機能がない。