はじめに
Django REST Framework (DRF) を使ってAPIを作成するとき、通常のモデルフィールドだけでなく、データを加工したり、関連モデルからデータを取得したりしたい場合があります。そんなときに便利なのが SerializerMethodField です。本記事では、このフィールドの使い方について詳しく解説します。
SerializerMethodFieldで実現可能なこと
1.モデルのデータを加工して取得する
2.指定したモデル以外の関連するモデルからもデータを取得する
これだけでは何のことかさっぱりだと思うので、以下に具体例を示します。ただし、ここではコードによる実装は行いません。
1.モデルのデータを加工する
以下のようなフィールドを持つUserモデルを仮定して考えます。
苗字(myoji) フィールド
名前(namae) フィールド
ここで、フルネームを取得したいとき、
SerializerMethodFieldを使えば、苗字フィールドと名前フィールドを結合(加工)することで実現できる。
2.指定したモデル以外の関連するモデルからもデータを取得する
例えば、Profile モデルと User モデルが1対1のリレーションを持っているケースを考えましょう。Profile モデルにユーザーの年齢(age)フィールドが存在するとします。しかし、APIでこの age を User モデルのシリアライズ時に一緒に取得したい場合、 SerializerMethodField を使用することで、 Profile モデルから User の情報に紐付いた年齢を取り出すことができます。
SerializerMethodFieldの基本的な書き方
次に、実際に SerializerMethodField をどのように定義するかを見てみましょう。まずはシンプルな例から始めます。
例1: モデルのデータを加工する
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
full_name = serializers.SerializerMethodField()
class Meta:
model = User
fields = ['myoji', 'namae', 'full_name']
# データの加工部分
def get_full_name(self, obj):
return f"{obj.myoji} {obj.namae}"
上記のコードでは、 User モデルの myoji と namae フィールドを結合して full_name として取得しています。
データを加工する関数の名前は、「get_<フィールド名>」にしてください。
システム側が、勝手にこの関数を探して実行してくれます。
引数のobjには、Metaクラス内で定義したモデルのオブジェクトが格納されています。ここでは、Userオブジェクトですね。
例2: 関連モデルのデータを取得する
class User(AbstractUser):
email = models.EmailField(unique=True)
myoji = models.CharField(max_length=30)
namae = models.CharField(max_length=30)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
age = models.IntegerField(null=True, blank=True)
以上の2つモデルを仮定して考える。
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
age = serializers.SerializerMethodField()
class Meta:
model = User
fields = ['username', 'email', 'age']
def get_age(self, obj):
return obj.profile.age
ここでは、 User モデルのシリアライザ内で、関連する Profile モデルから age を取得しています。これにより、 User オブジェクトに直接含まれないフィールドをAPIレスポンスに含めることができます。
まとめ
SerializerMethodField を使うことで、Django REST Framework のシリアライザに柔軟性を持たせることができます。単純なデータだけでなく、必要に応じて加工したり、関連モデルからの情報を取得したりすることで、より高度なAPI設計が可能になります。
最後に
少しでも参考になれば嬉しいです。
また、個人的に手書き機能を搭載したアプリを開発したいと考えているのですが、手書き機能の実装経験のある方やおすすめの方法等あれば、教えていただきたいです!!(UIkit, SwiftUI)
最後までお読み頂きありがとうございました!!