👌

[DRF]Serializerを使って、Modelに無い値をレスポンス含める

2023/02/12に公開

書くこと

  • SerializerMethodFieldを使って、モデルに無い値をレスポンスするSerializerの実装
  • Modelの@propertyを使って、モデルに無い値をレスポンスするSerializerの実装

利用する技術

  • Django REST Framework
  • rest_framework.generics.RetrieveAPIView
  • serializers.SerializerMethodField
  • Model.@property

想定シチュエーション

このようなUserモデルが定義されていたとき、

class User(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    # フルネームはカラムに存在しない!
    # full_name = models.CharField(max_length=200)

last_namefirst_nameを半角スペースで結合したfull_nameをレスポンスに含めたい。

レスポンス例

{
  "first_name": "mei",
  "last_name": "sei",
  "full_name": "sei mei"
}

方法論①: serializers.SerializerMethodFieldを使う

Serializerの定義

serializer/user_serializer.py


class UserSerializer(serializers.ModelSerializer):
    # モデルに含まれないカラムをSerializerMethodFieldで定義
    full_name = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = (
            "first_name",
            "last_name",
            "full_name",  # モデルのカラムに無い!!
        )

    # `get_`prefixをつけたメソッドの定義
    def get_full_name(self, obj):
        full_name = f"{obj.sei} {obj.mei}"
        return full_name

方法論②: Model.@propertyを使う

Serializerの定義

serializer/user_serializer.py

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = (
            "first_name",
            "last_name",
            "full_name",  # モデルのカラムに無い!!
        )

モデルに@propertyを定義

models/user.py

class User(models.Model):
    # (前略)
    @property
    def full_name(self):
        full_name = f"{self.sei} {self.mei}"
        return full_name

Discussion