[개발일지] 3일차 - django form, disabled input

grefer·2021년 10월 1일
0

오늘 (정확히는 어제) 한일

  • 도서산간 지역 배송 로직 구현
  • 회원가입 폼 수정

도서산간 지역을 구분하자

도서산간 지역으로 배송지가 바뀌면 이에 맞춰 배송비가 업데이트 되야 한다.
배송비를 다시 계산하는 경우는 다음의 경우인데,

  1. 기본 배송지가 도서산간인 경우: 결제 진행 페이지로 넘어갈 때 도서산간 배송비를 배송비에 더 얹는다.
  2. 기본 배송지가 도서산간이 아니었는데 도서산간으로 변경한 경우 혹은 그 반대: 서버에서 도서산간 배송비를 불러와서 그 만큼을 빼거나 더한다.

기존의 주소 모델은 우편번호와 도서산간 여부가 없었는데, 결국 추가하기로 했다. 그래서 1번의 경우 서버에서 주소 모델을 체크해서 도서산간 여부만 확인하면 된다.

사용자가 직접 주소를 변경하는 경우

문제는 2번인데, 사용자가 결제 진행 페이지에서 직접 주소 입력하는 경우 다음 우편번호 API의 리턴값으로 zipcode를 받는다. 이를 서버에 AJAX 요청을 보내고 서버는 zipcode를 기반으로 저번에 제작한 우편번호 체크 함수를 통해 여부를 판단하여 배송비의 증감액을 response에 보낸다. 클라이언트 사이드에서 이 응답을 기반으로 배송비와 전체 가격 필드를 업데이트 한다.

주소 모델을 바꿨으니...

결국 주소 모델에 우편번호, 도서산간 여부를 체크하는 함수를 넣음에 따라 주소모델을 사용하는 모든 페이지에 영향을 받게 된다. 특히 회원가입.

근데 주소 modelForm을 사용하는 페이지가 많기 때문에 form 단에서 데이터를 넣어줘야 큰 수정을 막을 수 있을 것 같았다.

django에서 formis_valid() 함수를 실행시켜 폼을 validation 하는데, 이 때 폼이 valid 하다면, is_valid()True를 리턴하고 cleaned_data 라는 이름의 리스트에 폼의 데이터를 저장한다.

cleaned_data에 데이터를 저장하기 위해 폼의 모든 필드에 대해 clean_(필드명)함수를 호출하여 데이터를 받는다.

만약 사용자가 주소를 입력하면 hidden상태의 zipcode 필드에 값이 들어간다. 하지만 이 주소가 도서산간인지 판정하려면 서버에 접근해야 하고, AJAX 요청을 해야 한다.
하지만, 이는 너무 번거롭다는 생각이 들어, 마지막에 폼이 제출될 때 zipcode를 가지고 도서산간 여부를 판정하는 함수를 실행시킨 다음 서버에 cleaned_data를 저장시키면 되겠다는 생각이 들었다.

def clean_is_jeju_mountain(self):
    zipcode = self.cleaned_data["zipcode"]

    return check_address_by_zipcode(int(zipcode))

이와 같이 도서산간 여부 필드(is_jeju_mountain)은 폼의 validation 과정에 값이 확정된다.

그럼 되야 하는건데

이렇게 폼을 바꾸고 회원가입을 완료하려 하는데, 자꾸만 제출을 해도 원래 페이지로 리다이렉트 되었다.
방금 바꾼 form에서 무언가 문제가 있다는 생각이 들었기에, 주소와 관련된 form만을 수정하고 계속 회원가입을 시도해도 결과는 같았다. 그래서 결국 전체 회원가입 form에 대해 오류를 체크해보니. 이런, 전화번호 필드가 비어있다는 것이다.

회원가입 과정에서 전화번호 인증을 받고 인증을 완료하면 더이상의 입력을 방지하기 위해 input을 disabled 상태로 변경하였는데, POST method상에서 disabled input은 서버로 제출이 안된다고 한다.

임시방편으로 인증을 완료해도 disabled되지 않도록 수정하였다.

우여곡절 끝에 회원가입 폼 수정 완료.

TIL

  • django form은 is_valid() 실행시 clean_(필드명) 함수를 실행함으로서 cleaned_data의 값을 채운다
  • html <form>은 POST method시 disabled 상태의 input의 데이터를 서버로 전송하지 않는다
profile
개발자가 되고싶다 열심히하자

0개의 댓글