2월 22, 2022

[django] westagram mission 5~6 를 진행하며 겪은 문제들(회원가입 비밀번호 암호화, 로그인시 JWT 발급)

 



미션 5 코멘트에 이런 과제를 주셨습니다.

  • phone_number가 꼭 들어가지 않아도 되도록 model을 수정하고
  • phone_number가 없어도 키에러가 나지 않고, 디폴트 값으로 무언가를 불러오도록 해주면 될 듯합니다
첫번째로, models.py의 phone_number 컬럼의 속성으로 null=True를 줄 지, blank=True를 줄 지 고민해보았습니다
  • null=True: 필드 값이 NULL로 저장되는 것 허용. DB의 열에 관한 설정.
    • 주어진 DB컬럼이 NULL값을 가질 수 있는지 정의
  • blank=True: 필드가 폼(입력 양식)에서 빈채로 저장되는 것 허용
    • 장고 관리자 및, 유효성과 관련돼 있습니다
    • blank가 False이면 해당 필드 없이 정보를 저장하고자 하면 유효성 검사에서 걸러지게 됩니다
    • blank=True로 할 시, 해당 필드가 없어도 정상적으로 동작합니다.
    • blank=True는 장고에 관련된 속성이기에 DB에 아무 영향도 주지 않습니다.
  • CharField, TextField에서는 null=True 를 설정할 시 문제가 생깁니다. Null의 "데이터 없음"이 문자열에서는 "빈 문자열"로 표현될 수 있기에. [데이터가 없는 상태]에 대해서 두가지 중복된 값을 가질 수 있게 됩니다. 
  • 따라서 CharField, TextField에는 null=True가 아닌 blank=True를 주는 것이 옳습니다

음... phone_number에 blank=True 속성을 추가해주면 될 듯 합니다.
메인에서 model만을 수정한 코드를 담은 브랜치를 따로 판 이후(현업에서는 모델을 수정할 때 무조건 이렇게 따로 브랜치를 파서 관리해줘야만 한다고 합니다) , 이를 PR후 merge받아서 main에서 migration을 시행하는데!  


에러가 발생합니다. users라는 테이블이 이미 있다고 합니다.
blank=True는 어차피 DB스키마에 영향을 미치지 않기에 migrate 해줄 필요가 없나 했더니, 그것 아닌가 봅니다


마이그레이션 실행자의 내부적인 모델 상태 그래프가 최신상태로 남기 위해 migration이 필요하다고 합니다, migration을 했으니 migrate를 하기 위해 다시 에러를 확인해봅니다.

해결법을 구글링하니 세가지 정도가 나옵니다.
  1. drop으로 users테이블 날린다
  2. python manage.py migrate --fake <appname> 으로 fake migrate한다
  3. 마이그레이션 파일 편집
3번을 하려고 0003_user_delete_users.py 파일을 열어봤습니다

db에 'users'라고 저장되는 테이블을 만든 이후, "Users"모델(db에선 'users'임)을 지워주려 합니다. 
지우고 -> 새로만들어야하는데
새로만들고 -> 지우려니 똑같은걸 또 만드려고 하는 에러가 나는 듯 합니다.

따라서 DeleteModel 부분을 CreateModel위로 올려줬습니다. 문제는 이렇게 수정하게 되면 DB가 날아가게 됩니다. 1번처럼 drop으로 테이블을 날린 것과 차이를 모르겠습니다.
DB에 별 정보가 없어서 망정이지, 매번 이렇게 할 수는 없을 듯 합니다.

다음번에 같은 에러와 마주한다면 fake migrate도 한번 시도해봐야겠습니다.

  • phone_number가 없어도 키에러가 나지 않고, 디폴트 값으로 무언가를 불러오도록 해주면 될 듯합니다
이를 해결해주기 위해 views에서 phone_number를 저장할 때 ,phone_number   = data["phone_number"],
가 아니라


이렇게 딕셔너리의 get메소드를 사용해주었습니다.
get메소드는 해당 키가 존재하지 않을 경우 , 디폴트 값을 저장해줍니다(아까 blank=True 해줬던거 기억하시죠?) 오른쪽의 빈 칸이 디폴트입니다.

어라? 근데 이렇게 저장하니 키에러가 뜹니다.
알고보니 "" 이렇게 디폴트 값으로 "빈 값"을 명시해줘야만 했습니다. 이렇게 하면 클라이언트가 전화번호 키 자체를 주지 않아도 해당 키에 디폴트로 ""값이 들어갑니다.