05의 개발 계발

[TIL] 230417 회원가입 조건 세분화하기 | if 본문

TIL

[TIL] 230417 회원가입 조건 세분화하기 | if

생각하는 코댕이 2023. 4. 18. 22:20
728x90

TIL 학습목표

  • if 문을 활용해 원하는 경우을 분리할 수 있다.
  • if 조건문을 활용해 회원가입 조건을 세분화 할 수 있다.

1) 문제점 (Problem)

지난주 진행하였던 Django 팀프로젝트에서 회원가입 시 프로필파일 업로드 용량제한 기능을 추가하는 과정에서

파일용량제한을 초과했다는 메세지가 나오지만, 회원가입이 되어버리는 issue가 발생했다.

회원가입 입력값

 

  1. 아이디*(필수)
  2. 비밀번호*(필수)
  3. 닉네임*(필수)
  4. 이메일*(필수)
  5. 프로필이미지(선택) - (500KB↓제한)
Case Error msg user 생성 작동
공란이 있을 경우 공란발생 메세지 X 정상작동
비밀번호가 불일치할 경우 비밀번호 불일치 메세지 X 정상작동
이미 존재하는 아이디일 경우 아이디 중복 메세지 X 정상작동
모두 기입하고,
이미지선택 안 할 경우
회원가입성공 O 정상작동
모두 기입하고,
500KB↓이미지선택 할 경우
회원가입성공 O 정상작동
모두 기입하고,
500KB↑이미지선택 할 경우
이미지 용량 초과 메세지 X msg는 나오나
user도 생성됨

2) 시도해본 것들 (Try)

▶기존코드리뷰

                else:
                    # 유저계정생성하여 DB저장  ★<1>
                    user=UserModel.objects.create_user(
                        username=username, #아이디
                        password=password, #비밀번호
                        nickname=nickname, #닉네임
                        email=email, #이메일
                    )
                    # 유저 이미지 불러와서 파일시스템에 저장하기 ★<2>
                    user_img = request.FILES.get("user_img",None) # 이미지 업로드 받아오기
                    
                    
                    if user_img:
                        # 파일 크기가 500KB를 초과하는 경우 에러 발생 ★<3>
                        if user_img.size > 500 * 1024:
                            return render(
                                request,
                                "user/signup_detail.html",
                                {"error_message": "야레야레~ 500KB 이상은 버겁다구~"},
                            )

위 코드를 살펴보자.

★<1> : 먼저 유저계정을 생성하여 DB에 저장한 뒤,
★<2> : 이미지를 불러와서 저장하고,
★<3> : 이미지의 크기를 판별한다.

이 과정대로라면 당연히 이미지 크기를 판별하기 전에, DB에 유저계정이 생성되게 된다.

그래서 [ 파일용량제한을 초과했다는 메세지가 나오지만, 회원가입이 되어버리는 issue가 발생했다. ]

 

+전체코드

더보기
# 회원가입
def sign_up(request):
    if request.method == "GET":  # 회원가입 페이지를 눌렀을 때
        return render(request, "user/signup.html")

    elif request.method == "POST":  # 회원가입정보 제출할 때
        username = request.POST.get("username", None)  # 회원 ID
        password = request.POST.get("password", None)  # 비밀번호
        password2 = request.POST.get("password2", None)  # 비밀번호 확인
        nickname = request.POST.get("nickname", None)  # 닉네임
        email = request.POST.get("email", None)  # 이메일       
        
        
        # 입력란이 모두 작성되어있다면 실행, 공란이 하나라도 있으면 else가 작동하여 에러메세지 출력
        if username and password and password2 and nickname and email:
            if password != password2:
                return render(
                    request,
                    "user/signup.html",
                    {"error_message": "[비밀번호불일치!] 진정하고 천천히 다시써봐요 예?"},
                )
            else:
                exist_user = get_user_model().objects.filter(username=username)
                if exist_user:
                    # 중복된 ID라면 에러메세지 출력
                    return render(
                        request,
                        "user/signup.html",
                        {"error_message": "[중복 발견!] 이미 있는 ID입니다. 아시겠어요?"},
                    )
                else:
                    # 유저계정생성하여 DB저장
                    user=UserModel.objects.create_user(
                        username=username, #아이디
                        password=password, #비밀번호
                        nickname=nickname, #닉네임
                        email=email, #이메일
                    )
                    # 유저 이미지 불러와서 파일시스템에 저장하기
                    user_img = request.FILES.get("user_img",None) # 이미지 업로드 받아오기
                    
                    
                    if user_img:
                        # 파일 크기가 500KB를 초과하는 경우 에러 발생
                        if user_img.size > 500 * 1024:
                            return render(
                                request,
                                "user/signup_detail.html",
                                {"error_message": "야레야레~ 500KB 이상은 버겁다구~"},
                            )
                        # 파일을 시스템에 저장 | FileSystemStorage | DB가 아닌 시스템으로 지정한 dir에 저장
                        storage = FileSystemStorage()
                        # 
                        file_saved = storage.save(user_img.name, user_img)

                        # 저장한 파일의 경로를 url로 추출
                        uploaded_file_url = storage.url(file_saved)

                        # 신규 회원의 id 추출 후 업데이트
                        check = UserModel.objects.filter(id=user.id)
                        check.update(user_img=uploaded_file_url)
                    
                # 회원가입 성공시 로그인 페이지로 이동
                return redirect("sign-in")
        # 공란이 하나라도 있으면 else가 작동하여 에러메세지 출력
        else:
            return render(
                request,
                "user/signup.html",
                {"error_message": "[빈칸 발견!] 공란이 빤히 보이는데, 미치셨어요?"},
            )

▶조건문 위치 변경 및 추가

        user_img = request.FILES.get("user_img",None) # 이미지 업로드 받아오기 ★<1>
        
        ...
        	...
                else:
                    # 500KB 보다 큰 파일을 업로드한다면 경고메세지 
                    if user_img and user_img.size > 500 * 1024:	#★<2>
                        return render(
                            request,
                            "user/signup.html",
                            {"error_message": "[용량 초과!] 야레야레~ 500KB 이상은 버겁다구~"},
                        )
                    else:
                        # 유저계정생성하여 DB저장	★<3>
                        user=UserModel.objects.create_user(
                            username=username, #아이디
                            password=password, #비밀번호
                            nickname=nickname, #닉네임
                            email=email, #이메일
                        )
              		...
              ...
          ...

위 처럼 코드의 순서와 조건문을 고쳐보았다.

★<1> : 먼저 이미지를 불러와서 저장하고,
★<2> : 이미지가 존재하면서 크기가 크다면 에러메세지를 주도록 하고,
★<3> : 아니라면 유저계정을 생성하여 DB에 저장한다

이 과정대로라면 ★<3>에는
이미지 선택이 없을 때 + 이미지 크기가 500KB↓일 때 만 
모두 해당되어 DB에 유저계정이 생성되게 된다.

 

+전체코드

더보기
# ============================= 회원가입 =============================
def sign_up(request):
    if request.method == "GET":  # 회원가입 페이지를 눌렀을 때
        return render(request, "user/signup.html")

    elif request.method == "POST":  # 회원가입정보 제출할 때
        username = request.POST.get("username", None)  # 회원 ID
        password = request.POST.get("password", None)  # 비밀번호
        password2 = request.POST.get("password2", None)  # 비밀번호 확인
        nickname = request.POST.get("nickname", None)  # 닉네임
        email = request.POST.get("email", None)  # 이메일       
        user_img = request.FILES.get("user_img",None) # 이미지 업로드 받아오기
        
        
        # 입력란이 모두 작성되어있다면 실행, 공란이 하나라도 있으면 else가 작동하여 에러메세지 출력
        if username and password and password2 and nickname and email:
            if password != password2:
                return render(
                    request,
                    "user/signup.html",
                    {"error_message": "[비밀번호불일치!] 진정하고 천천히 다시써봐요 예?"},
                )
            else:
                exist_user = get_user_model().objects.filter(username=username)
                
                if exist_user:
                    # 중복된 ID라면 에러메세지 출력
                    return render(
                        request,
                        "user/signup.html",
                        {"error_message": "[중복 발견!] 이미 있는 ID입니다. 아시겠어요?"},
                    )
                else:
                    # 500KB 보다 큰 파일을 업로드한다면 경고메세지
                    if user_img and user_img.size > 500 * 1024:
                        return render(
                            request,
                            "user/signup.html",
                            {"error_message": "[용량 초과!] 야레야레~ 500KB 이상은 버겁다구~"},
                        )
                    else:
                        # 유저계정생성하여 DB저장
                        user=UserModel.objects.create_user(
                            username=username, #아이디
                            password=password, #비밀번호
                            nickname=nickname, #닉네임
                            email=email, #이메일
                        )
                    if user_img:
                        # 파일을 시스템에 저장 | FileSystemStorage | DB가 아닌 시스템으로 지정한 dir에 저장
                        storage = FileSystemStorage() #실제로 이미지 파일이 저장되는 것
                        # 
                        file_saved = storage.save(user_img.name, user_img)

                        # 저장한 파일의 경로를 url로 추출
                        uploaded_file_url = storage.url(file_saved)

                        # 신규 회원의 id 추출 후 업데이트
                        check = UserModel.objects.filter(id=user.id)
                        check.update(user_img=uploaded_file_url)
                
                    # 회원가입 성공시 로그인 페이지로 이동
                    return redirect("sign-in")
        # 공란이 하나라도 있으면 else가 작동하여 에러메세지 출력
        else:
            return render(
                request,
                "user/signup.html",
                {"error_message": "[빈칸 발견!] 공란이 빤히 보이는데, 미치셨어요?"},
            )

3) 해결 (Solution)

if 문의 구조와 순서를 변경함으로써 해결

# ============================= 회원가입 =============================
def sign_up(request):
    if request.method == "GET":  # 회원가입 페이지를 눌렀을 때
        return render(request, "user/signup.html")

    elif request.method == "POST":  # 회원가입정보 제출할 때
        username = request.POST.get("username", None)  # 회원 ID
        password = request.POST.get("password", None)  # 비밀번호
        password2 = request.POST.get("password2", None)  # 비밀번호 확인
        nickname = request.POST.get("nickname", None)  # 닉네임
        email = request.POST.get("email", None)  # 이메일       
        user_img = request.FILES.get("user_img",None) # 이미지 업로드 받아오기
        
        
        # 입력란이 모두 작성되어있다면 실행, 공란이 하나라도 있으면 else가 작동하여 에러메세지 출력
        if username and password and password2 and nickname and email:
            if password != password2:
                return render(
                    request,
                    "user/signup.html",
                    {"error_message": "[비밀번호불일치!] 진정하고 천천히 다시써봐요 예?"},
                )
            else:
                exist_user = get_user_model().objects.filter(username=username)
                
                if exist_user:
                    # 중복된 ID라면 회원가입창으로 돌아가기
                    # 영오: 이미 있는 ID입니다. 새로 지정해주세요. 메세지 떠야합니다.
                    return render(
                        request,
                        "user/signup.html",
                        {"error_message": "[중복 발견!] 이미 있는 ID입니다. 아시겠어요?"},
                    )
                else:
                    # 500KB 보다 큰 파일을 업로드한다면 경고메세지
                    if user_img and user_img.size > 500 * 1024:
                        return render(
                            request,
                            "user/signup.html",
                            {"error_message": "[용량 초과!] 야레야레~ 500KB 이상은 버겁다구~"},
                        )
                    else:
                        # 유저계정생성하여 DB저장
                        user=UserModel.objects.create_user(
                            username=username, #아이디
                            password=password, #비밀번호
                            nickname=nickname, #닉네임
                            email=email, #이메일
                        )
                    if user_img:
                        # 파일을 시스템에 저장 | FileSystemStorage | DB가 아닌 시스템으로 지정한 dir에 저장
                        storage = FileSystemStorage() #실제로 이미지 파일이 저장되는 것
                        # 
                        file_saved = storage.save(user_img.name, user_img)

                        # 저장한 파일의 경로를 url로 추출
                        uploaded_file_url = storage.url(file_saved)

                        # 신규 회원의 id 추출 후 업데이트
                        check = UserModel.objects.filter(id=user.id)
                        check.update(user_img=uploaded_file_url)
                
                    # 회원가입 성공시 로그인 페이지로 이동
                    return redirect("sign-in")
        # 공란이 하나라도 있으면 else가 작동하여 에러메세지 출력
        else:
            return render(
                request,
                "user/signup.html",
                {"error_message": "[빈칸 발견!] 공란이 빤히 보이는데, 미치셨어요?"},
            )

4) 알게 된 점  (Learnd)

코드리뷰가 참 중요함을 느끼게 되었다.
알고리즘을 풀고, 다른 사람들의 코드를 보며 코드 보는 눈을 길러두었던게 큰 도움이 되었던 것 같다.
그리고 주석을 달면서 논리의 흐름을 기록하는 것이 제법 적응되었다.
하지만 앞으로는 필요한 주석만 작성할 수도 있도록 연습해야겠다.

728x90