1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【DRF(Django REST framework)】エラーメッセージの"この項目"をverbose_nameに置き換えたい

Posted at

前提

  • フィールドに氏名を定義している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に変換する処理を定義した
  • 詳しい処理内容はコメント参照

参考資料

  • ありがたや

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?