
이 단계에서는 사용자에게 비밀번호1, 비밀번호 2를 입력받아 간단한 유효성 검사 후 request.session에 저장하는 작업이 이루어집니다.
구현 중 parser와 Serializer의 개념이 혼동되어 이 둘의 차이를 다시 정리해 보았습니다.
클라이언트의 요청은 그 데이터의 포맷이 다양합니다.
parser는 뷰(View)에서 주로 사용되며, 특정 요청 데이터의 형식을 입력받아 구조 분석 후 데이터를 추출하하여 이를 request.data에 저장합니다.
django DRF에서 지원하는 parser는 다음과 같습니다.
1) FormParser
2) MultiPartParser
3) JsonParser
serializer의 기능은 기본적으로 직렬화, 역직렬화아지만 다향한 기능을 수행합니다.
django의 모델을 손쉽게 직렬화해주는 객체입니다.
Serializer는 아래와 같이 구현하였습니다.
class ValidatePwdSerializer(serializers.Serializer):
password1 = serializers.CharField(
write_only=True,
required=True,
allow_blank=False,
allow_null=False,
validators=[validate_password],
error_messages={"required": "비밀번호는 반드시 입력 되어야 합니다."},
)
password2 = serializers.CharField(
write_only=True,
required=True,
)
def validate(self, data):
password1 = data.get("password1")
password2 = data.get("password2")
if password1 and password2 and password1 != password2:
raise serializers.ValidationError("비밀번호가 일치하지 않습니다. 다시 입력해주세요.")
return data
serializer에서는 2개의 유효성 검사가 진행됩니다.
우선, 필드 옵션으로 지정한 validate_password를 통해 아래 내용을 검증합니다.
그리고 나서 serializer의 validate를 오버라이드하여 입력한 비밀번호1과 비밀번호2가 일치하는지 확인합니다.
'데이터 검증이 없다면 백엔드 서버가 존재하는 의미가 사라진다.'
비밀번호 Validation을 구현하면서 알게된 추가적인 내용을 정리하겠습니다.(‘•̀ ▽ •́ )✎
serializser의 작동방식은 크게 세 가지로 나누어볼 수 있습니다.
① serializer 인스턴스를 생성, Serializer(data=request.data)
② 데이터를 검증, is_valid()
③ 저장 , save()
serializser의 모든 validator와 Validation은 is_valid()가 호출될 때 전부 수행 됩니다.
serializser의 Validation은 다음과 같이 구성할 수 있습니다.
필드별 검증 :필드의 옵션을 지정하거나 validator를 지정하거나 커스텀한다.
객체 수준 검증 : validator와 validation 메서드를 지정 또는 커스텀한다.(통합 커스텀과 필드 커스텀)
Serializer의 유효성을 검증하는 로직을 작성할 때는 일반적으로 옵션을 부여하는 방식을 사용하며 이러한 방식이 권장됩니다.
옵션을 부여하는 방식이 아니라 개발자가 직접 구현하는 validation 방식은
필드 커스텀과 통합 커스텀 방식이 있습니다.
① 필드 커스텀의 예
필드 커스텀 Validation 메서드를 validate_필드명 메서드로 선언하면 DRF가 이 메서드를 자동으로 인식하고 유효성 검증 시 해당 메서드를 함께 수행합니다!⎝⍥⎠
이 방식은 간단한 validation을 작성할 때나(알파벳만 사용하였는지) 데이터를 정제해주는 작업 시(공백과 같은 불필요한 값제거) 사용합니다.
② 통합 커스텀
복합적인 데이터가 함께 검증되어야 하는 로직 또는 비즈니스 수준에서 검증이 필요할 때 사용합니다.(하루에 회원 가입을 100명만 할 수 있다는 정책이 존재)
③ 여러필드 또는 객체 수준에서 복합적 유효성 검사
validator를 사용합니다.
마지막으로 유효성 검증 로직은 serializer 내부에 if 문을 최대한 사용하지 않고 작성하는 것이 재사용성을 고려했을 때 효율적입니다.
복잡했던 serializer의 Validation 과정이 조금 더 이해되었습니다!
API에서는 serializer.is_valid() True인 경우에 request.session에 유효성 검사가 완료된 비밀번호를 저장하도록 하였습니다.
class ValidatePwdAPIView(APIView):
serializer_class = ValidatePwdSerializer
def post(self, request, *args, **kwargs):
serializer = ValidatePwdSerializer(data=request.data)
if serializer.is_valid():
request.session["password1"] = serializer.validated_data["password1"]
request.session["password2"] = serializer.validated_data["password2"]
return Response(
{"message": "입력 비밀번호가 일치 합니다."},
status=status.HTTP_200_OK,
)
else:
errors = serializer.errors
return Response(
errors,
status=status.HTTP_400_BAD_REQUEST,
)
① 초기 데이터 설정: request.data가 initial_data로 설정됩니다.
② 필드별 검증: password1과 password2 필드에 대해 개별 검증이 수행됩니다.(run_validation)
③ 객체 수준 검증: validate 메서드가 호출되어 password1과 password2가 일치하는지 확인합니다.
④ 결과 저장 및 반환: 검증이 성공하면, 검증된 데이터가 validated_data 속성에 저장되고, True가 반환됩니다.