Make組ブログ

Python、Webサービスや製品開発、ライブラリー開発についてhirokikyが書きます

DjangoRestFrameworkのSerializerから関数/メソッドの結果をフィールドの値として返す

DjangoRestFrameworkのSerializer(ModelSerializer)で、フィールドの値を関数/メソッドの結果で返したいことがあります。 これはバリデーションとしてSerializerを使うのでなく、モデルから辞書に値を変換したい場合の話です。

例えば、フィールドの日時が何日前かや、何かしら加工した値が欲しい場合です。 もちろんモデル自体にプロパティとして実装すれば疑問なくフィールドとして使えますが、そのSerializerでだけやりたい処理の場合はこの方法が有効です。

以下の例では Foo モデルに、 bar というフィールドでメソッドの結果を返すようにしています。 serializers.SerializerMethodField を使ってできます。この場合 bar はリードオンリーのフィールドになります。

class FooSerializer(serializers.ModelSerializer):
    bar = serializers.SerializerMethodField()

    def get_bar(self, obj):
        return obj.bar.title()

    class Meta:
        model = Foo
        fields = (
            ...
            'bar'
        )

SerializerMethodField に何も指定しないと、メソッド名は get_bar がデフォルトで指定されます。 メソッド名を特別に指定したい場合は SerializerMethodField("calc_bar") のようにします。

でもこのときにメソッド名もフィールドと同じ名前(上記では bar )にしてしまうと、フィールドが無効になってしまうので気をつけてください。 (名前が被ってしまうので、クラス内の値として後に書いたものだけが有効になってしまう)。

www.django-rest-framework.org