Edited at

Django REST framework の ModelSerializer の Field Mapping を変えたい


概要


  • REST framework には ModelSerializer という Django の Model を指定すると、いい感じにフィールドが生えた Serializer を生成してくれる機能があります。

  • この ModelSerializer は 内部では Django の ModelField に応じて restframework の Field とマッピングさせています。

  • 例えば django.models.TextFieldrestframwork.fields.CharField にマッピングされています。

  • このマッピングのカスタマイズできるといいですよねという話です。


例えば

class LocalDateTimeField(serializers.DateTimeField):

""" localize した時間を扱う DateTimeField
"""

def to_representation(self, value):
value = timezone.localtime(value)
return super(LocalDateTimeField, self).to_representation(value)

こういうカスタムフィールドを作ったら、個別の Serializer にそのまま設定すれば利用可能です。

class HogeSerializer(serializers.ModelSerializer):

created_at = LocalDateTimeField()

class Meta:
model = Hoge
fields = "__all__"

ですが、毎回個別のSerializerに設定するのは、漏れもあるしちょっと面倒です。 そこで ModelSerializer.serializer_field_mapping の設定を変えるような MyModelSerializer を作ってみます。

from django.db import models

class MyModelSerializer(serializers.ModelSerializer):

serializer_field_mapping = (
serializers.ModelSerializer.serializer_field_mapping.copy()
)
serializer_field_mapping[models.DateTimeField] = LocalDateTimeField

django.models.DateTimeField が LocalDateTimeField にマッピングされたMyModelSeriazer ができました。

あとは下記のように MyModelSerializer を継承するだけです。

class HogeSerializer(MyModelSerializer):

class Meta:
model = Hoge
fields = "__all__"

これで MyModelSerializer を継承している全ての Serializer は全てのDatetimeFieldがローカライズされるようになります。

以上です。


参考