AI 본캠프/TIL

25/01/24 TIL(17주차 금요일)

impact7608 2025. 1. 24. 21:52
  • 비밀번호 변경 기능 Issue
    1. 모든 요청에 대해 성공 상태(HTTP 200)가 반환됨: 성공과 실패를 구분하지 못함.
    2. 기능 작동 실패: JSON 응답 처리 도중 비밀번호 변경이 제대로 작동하지 않음.
    문제 원인 분석
    • form_valid와 form_invalid 메서드에서 JSON 응답을 반환하며 Django 기본 PasswordChangeView의 처리 과정을 제대로 상속하지 않았음.
    • form_valid에서 기본 구현을 호출하지 않아 비밀번호 변경 로직이 동작하지 않았음.
    • 인증되지 않은 사용자의 요청을 처리하지 못함.
    • 기본 Django의 비밀번호 변경기능을 불러오는 super()로직이 포함 되었어야함
    해결 방안 및 코드 수정
    • form_valid와 form_invalid에서 Django 기본 구현을 호출한 뒤, 적절한 JSON 응답을 반환하도록 수정.
    2. 인증 상태 확인 및 처리
    • dispatch 메서드를 오버라이드하여 인증되지 않은 사용자 요청에 대해 명확한 HTTP 401 상태와 메시지 반환.
    3. HTTP 상태 코드 사용
    • 성공(200)과 실패(400)에 적절한 HTTP 상태 코드를 설정.
    4. 기본 Django의 비밀번호 변경기능 불러오기
    • super()로직 포함
    <코드 변천사>
    1. 기존 코드 : 비밀번호 변경기능은 동작하나 여러가지 실패상황에 대한 상태도 200성공 상태가 반환 되는 문제가 있었음.
    class CustomPasswordChangeView(PasswordChangeView):
        template_name = 'profile.html'
        success_url = reverse_lazy('login')  # 로그인 페이지로 리디렉션
    
        def form_valid(self, form):
            # 성공 메시지 추가
            messages.success(self.request, "비밀번호가 성공적으로 변경되었습니다. 다시 로그인해주세요.")
            return super().form_valid(form)
    
        def form_invalid(self, form):
            # 실패 메시지 추가
            messages.error(self.request, "비밀번호 변경에 실패했습니다. 입력 정보를 확인해주세요.")
            return super().form_invalid(form)
    
    1. 수정 코드 : CustomPasswordChangeView의 초기 구현은 Django 기본 PasswordChangeView를 상속하여 비밀번호 변경 성공 및 실패 시 메시지를 추가하는 단순한 구조였습니다. 이후 JSON 형태로 클라이언트에 응답을 반환하기 위해 수정했지만, 비밀번호 변경 기능 자체가 작동하지 않는 문제가 발생했습니다.
    원인 분석
    1. Django 기본 로직 호출 누락
    2. form_valid와 form_invalid 메서드에서 Django의 기본 PasswordChangeView 로직을 호출하는 super()가 생략되었습니다. 이로 인해 실제 비밀번호 변경이 이루어지지 않았습니다.
    class CustomPasswordChangeView(PasswordChangeView):
        template_name = 'profile.html'
        success_url = reverse_lazy('login')
    
        def form_valid(self, form):
            messages.success(self.request, "비밀번호가 성공적으로 변경되었습니다. 다시 로그인해주세요.")
            return JsonResponse({"success": True, "message": "비밀번호가 성공적으로 변경되었습니다."})
    
        def form_invalid(self, form):
            errors = form.errors.as_json()
            return JsonResponse({"success": False, "errors": errors}, status=400)
    
    
    1. 최종 코드 :
    기본 로직 유지
    PasswordChangeView
    
    가 비밀번호 변경을 처리하도록를 호출하며, 이를 바탕으로 추가적인 JSON 응답을 구현.트러블슈팅 결과
    1. 비밀번호 변경 로직 복원
    2. super().form_valid() 및 super().form_invalid() 호출로 Django 기본 기능이 정상적으로 작동.
    3. JSON 응답과 HTTP 상태 코드 개선
    4. 클라이언트가 서버 응답을 명확히 이해할 수 있도록 JSON 메시지와 HTTP 상태 코드를 통합.
    5. 유연하고 유지보수 가능한 코드
    6. 확장 가능성이 높은 구조로 작성되어 추가 요구사항에도 쉽게 대응 가능.
    교훈
    • 기존 로직 보존의 중요성: 기본 동작을 무조건 대체하기보다는 필요한 부분만 확장하거나 덮어쓰는 방식이 안전함.
    • 명확한 통신 규약: 클라이언트와 서버 간의 의사소통을 위해 HTTP 상태 코드와 메시지를 활용하는 것이 중요.
    • 테스트의 필요성: 코드 수정 후 발생할 수 있는 예기치 않은 오류를 방지하기 위해 유닛 테스트와 통합 테스트가 필수
    • 대부분의 실수가 urls.py에서 발생했었음. urls.py의 기본 구조 학습이 더 필요함.
  • class CustomPasswordChangeView(PasswordChangeView): template_name = 'profile.html' success_url = reverse_lazy('login') # 로그인 페이지로 리디렉션 def form_valid(self, form): # 비밀번호 변경 성공 시 기본 동작 유지 response = super().form_valid(form) # 추가: 상태 코드와 JSON 응답 반환 return JsonResponse({"message": "비밀번호가 성공적으로 변경되었습니다."}, status=200) def form_invalid(self, form): # 비밀번호 변경 실패 시 기본 동작 유지 super().form_invalid(form) # 추가: 상태 코드와 JSON 응답 반환 return JsonResponse( {"message": "비밀번호 변경에 실패했습니다. 입력 정보를 확인해주세요."}, status=400, ) def dispatch(self, request, *args, **kwargs): # 인증되지 않은 사용자 처리 if not request.user.is_authenticated: return JsonResponse({"message": "인증되지 않은 사용자입니다."}, status=401) return super().dispatch(request, *args, **kwargs)
  • super()
  • Django의
  • 1. 기본 동작 유지하면서 JSON 응답 추가
  • 기존 CustomPasswordChangeView 구현은 비밀번호 변경 성공 또는 실패 여부를 사용자에게 JSON 형태로 명확히 전달하여 상태에 따라 다른 동작을 구현할 계획이었습니다. 그러나 아래와 같은 문제가 발생했습니다: