[Django REST Framework]シリアルライザのクリーンアップ
Serializers:クエリーセットやモデルインスタンスなどの複雑なデータをJSON、XMLなどのコンテンツタイプに変換し、逆にJSON、XMLなどのデータをクエリーセットやモデルインスタンスに変換します.(deserialize)
create、updateなどの逆シーケンス化プロセスが必要な場合、検証用の関数を呼び出す必要があります.モデルで指定するフィールドタイプとフィールド条件(Unique=True、blank=Falseなど)のデータ が満たされているかどうかを確認します.条件を満たす場合、validate dataに有効性を通過するデータを加える. 以降のシーケンサ.save()はリソースを作成または更新します.
データが検証に失敗した場合、エラー応答が必要になりますが、簡単に次の内容を作成した場合、検証に失敗した場合、メッセージなしで500(内部サーバエラー)ステータスコードが返されます. if文を用いたエラー処理
serializer.errorsによってkey、value形式の有効性フィールドおよびその理由(ex.userwith this emailは既に存在する)を介して応答メッセージに送信できません. raise exceptionを用いたエラー処理
検証されたデータ(validate data)はシーケンス化器です.リソースが存在しない場合はsave()に移動し、存在する場合はupdate()に移動します.差異 create()はvalidate dataパラメータを受け入れます. update()は、インスタンスとvalidate dataの2つのパラメータを受信し、インスタンスを返します.(既存のリソースを更新する必要があるインスタンス)
is valid()で検証するほか、カスタムで検証することもできます.まず、モデルで指定したフィールドタイプ/条件を順番に検証し、カスタム検証を行います.
複数のフィールドにアクセスする必要がある場合に使用する検証は、validate()関数で作成できます.
1つのフィールドに対して有効性チェックを行う場合、field-level有効性チェックは
serializer.is_valid()
create、updateなどの逆シーケンス化プロセスが必要な場合、検証用の関数を呼び出す必要があります.
serializer.is valid()エラーの作成
データが検証に失敗した場合、エラー応答が必要になりますが、簡単に次の内容を作成した場合、検証に失敗した場合、メッセージなしで500(内部サーバエラー)ステータスコードが返されます.
serializer = RegisterSerializer(data=request.data)
serializer.is_valid()
serializer.save()
return Response({'message': message.REGISTER_SUCCESS}, status=status.HTTP_201_CREATED)
serializer = RegisterSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response({'message': message.REGISTER_SUCCESS}, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
上記のコードに示すように、if文を使用して検証に失敗した場合にエラー処理を行うことができます.serializer.errorsによってkey、value形式の有効性フィールドおよびその理由(ex.userwith this emailは既に存在する)を介して応答メッセージに送信できません.
serializer = RegisterSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response({'message': message.REGISTER_SUCCESS}, status=status.HTTP_201_CREATED)
上記のコードのように、serializer.is_valid(raise_exception=True)
を使用すると、コードを減らしてエラー処理を行うことができます.検証に失敗した場合は、独自にシーケンス化できます.errorsとともに、ステータスコードも400コードを返し、指定する必要はありません.serializer.save()
検証されたデータ(validate data)はシーケンス化器です.リソースが存在しない場合はsave()に移動し、存在する場合はupdate()に移動します.
# serializer.save() 내부 코드 중 일부
# 기존에 존재하는 리소스이면 update, 아니면 create로 처리
if self.instance is not None:
self.instance = self.update(self.instance, validated_data)
assert self.instance is not None, (
'`update()` did not return an object instance.'
)
else:
self.instance = self.create(validated_data)
assert self.instance is not None, (
'`create()` did not return an object instance.'
)
create、update関数は、追加条件を上書きすることができます.from django.contrib.auth.hashers import make_password
class RegisterSerializer(serializers.ModelSerializer):
security_code = SecurityCodeSerializer(read_only=True)
password2 = serializers.CharField(max_length=128, read_only=True)
class Meta:
model = User
fields = [
'id',
'email',
'password',
'password2',
'nickname',
'name',
'phone',
'security_code'
]
def create(self, validated_data):
validated_data['password'] = make_password(validated_data['password'])
return super().create(validated_data)
以上のように、Serializersクラスは、リソースの作成時にcreate関数を作成し、条件を追加します.(パスワードが復号されて保存される)、update関数も同様に変更されます.
#update 예시
def update(self, instance, validated_data):
new_password = make_password(validated_data['password'])
instance.password = new_password
instance.save()
return instance
validation
is valid()で検証するほか、カスタムで検証することもできます.まず、モデルで指定したフィールドタイプ/条件を順番に検証し、カスタム検証を行います.
object_level validation
複数のフィールドにアクセスする必要がある場合に使用する検証は、validate()関数で作成できます.
class ResetPasswordSerializer(serializers.ModelSerializer):
security_code = SecurityCodeSerializer(read_only=True)
password2 = serializers.CharField(read_only=True)
class Meta:
model = User
fields = [
'security_code',
'email',
'password',
'password2'
]
def validate(self, data):
input_password = data['password']
input_email = data['email'].split("@")[0]
nickname = User.objects.get(email=data['email']).nickname
if not 7 < len(input_password) < 13:
raise serializers.ValidationError(message.PASSWORD_LENGTH_ERROR)
if not any(char.isdigit() for char in input_password):
raise serializers.ValidationError(message.PASSWORD_COMBINATION_ERROR)
if not any(char.isalpha() for char in input_password):
raise serializers.ValidationError(message.PASSWORD_COMBINATION_ERROR)
if input_password in input_email \
or input_email in input_password:
raise serializers.ValidationError(message.PASSWORD_UNIQUE_ERROR)
if input_password in nickname \
or nickname in input_password:
raise serializers.ValidationError(message.PASSWORD_UNIQUE_ERROR)
return data
前述したように、パスワードリセットの検証が必要であり、複数のフィールドにアクセスする必要がある場合、validate()関数を使用してobject-levelの検証を作成できます.field_level validation
1つのフィールドに対して有効性チェックを行う場合、field-level有効性チェックは
validate_필드명(self, value)
形式で行うことができます.class PhoneVerifySerializer(serializers.ModelSerializer):
class Meta:
model = PhoneVerification
fields = [
'id',
'phone',
'security_code'
]
def validate_phone(self, value):
if any(num.isalpha() for num in value):
raise serializers.ValidationError(message.PHONE_NUMBER_ERROR)
return value
field-levelなので、パラメータとして受信した値はphoneデータです.Reference
この問題について([Django REST Framework]シリアルライザのクリーンアップ), 我々は、より多くの情報をここで見つけました https://velog.io/@dhleeone/Django-REST-Framework-Serializers-정리テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol