前提
- フィールドに氏名を定義しているUserモデルクラスを作成する
- ユーザー登録・更新処理時には、以下のようなシリアライザーを作成する
Userモデルクラス
class User(BaseModel):
name = models.CharField(verbose_name='氏名' blank=False)
Userシリアライザー
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
目的
- ユーザーデータがPOSTされた際に、氏名がブランクの場合は以下のようなDRFデフォルトのエラーメッセージを返す
{"name":["この項目は空にできません。"]}
-
この項目
が気に入らない -
key
を参照してフロント側で変換してもいいが、せっかくバックエンド側にverbose_name
を定義しているのでバックエンド側で変換したい
対策
- こんな感じで実現
エラーメッセージをverbose_nameに変換するカスタムModelSerializerクラス
from rest_framework import serializers
from rest_framework.exceptions import ErrorDetail
class CustomModelSerializer(serializers.ModelSerializer):
@property
def errors(self):
# エラーを取得
errors = super().errors
# verbose_name変換後エラーメッセージ
verbose_errors = dict()
# Modelクラスからverbose_nameを属性に持っているフィールドを取得
fields = {field.name: field.verbose_name for field in
self.Meta.model._meta.get_fields() if hasattr(field, 'verbose_name')}
# エラー分ループ
for field_name, error in errors.items():
# 「この項目」をverbose_nameに変換したErrorDetailを格納するリスト
changed_error = list()
# エラーが発生したフィールドがverbose_nameを持っているか
if field_name in fields:
for e in error:
# この項目をverbose_nameに置き換える
changed_error.append(ErrorDetail(str(e).replace('この項目', str(fields[field_name])), e.code))
# verbose_nameに変換したエラーメッセージを設定
verbose_errors[field_name] = changed_error
else:
# 元のエラーメッセージを設定
verbose_errors[field_name] = error
return verbose_errors
Userモデルクラス
class User(CustomModelSerializer):
name = models.CharField(verbose_name='氏名' blank=False)
簡単解説
- Serializerでエラーが発生すると、プロパティの
errors
にエラーメッセージ(ErrorDetail(string='エラーメッセージ' code='エラー種別')
)が格納される - そのため、
errors
プロパティをオーバーライドして、この項目
をverbose_name
に変換する処理を定義した - 詳しい処理内容はコメント参照
参考資料
- ありがたや