본문 바로가기
django

2021.01.18 django User Custom Model

by 해맑은 코린이 2021. 1. 18.

2021.01.18 _django User custom model _정리노트

 

 

드디어.. 올 것이 왔군 진짜 이것때문에 많이 고생했다 했어... 지금도 아마 블로그를 쓰면서 보면 엉망인 코드가 많을 것 같아 두렵지만... 한번 그래도 정리하면서 다시보기..!! 

 

 

 

먼저 장고프로젝트를 시작할 때 가장 먼저 정의되어야하는 것은 유저이다. 유저를 정하지 않고 마이그레이션을 하게 되면, 장고에서는 어드민을 기본으로 마이그레이션을 해버린다. 그래서 나중에 커스텀유저를 만들고 마이그레이션을 해버리면 충돌이 나게 된다.

 

나는 유저 커스텀...에다가 이메일 인증까지 구현해야해서 사실 겁나기도 해서 맨 마지막으로 미뤘더니 꽤 고치기 힘들었...^^ ( 데이터 베이스 결국 다 날림.. ) 

쨋든 프로젝트를 시작하면 유저를 맨 먼저 만드는 것을 추천한다. 

 

또한 유저는 서비스를 만들고 중간에 데이터 베이스를 변경하는 것이 어려우니, 한 번 유저모델을 커스텀하기 시작하면 신중하게 완벽하게 짜는 것일 필요하다. ( 물론 나는 실패 !^^ )

 


 

 

또한 유저모델을 커스텀할 때에는 두 가지의 방법이 있는데, 모든 사용자 관련 정보를 한 유저 모델에 보관하면, 관련 모델에 대한 옵션, 복잡한 데이터 베이스 쿼리가 필요하지 않지만, 앱별로 사용자 정보를 유저 모델로 저장하는 것이 적절할 때도 있다. 이를 통해 다른 앱과 충돌하거나 위반하지 않고, 각 앱이 원하는 자체 유저 모델을 지정할 수도 있다. 

 

나는 일단 한 유저모델만 만들어서, 한 모델안에 유저의 데이터베이스를 전부 담는 방식을 선택했다.

 

또한, 장고에서 제공하는 기본 인증 백엔드를 사용하고, 유저 커스텀 중에 가장 쉽게 할 수 있는 AbstractBaseUser에서 상속하여 내 프로젝트에 필요한 기능을 커스텀 하는 방식을 사용했다. 

 AbstractBaseUser 는 기본 해시된 비밀번호, 토큰화된 암호 재설정을 포함하여 유저모델의 핵심 구현을 제공한다. 

우리는 이를 상속하고, 몇 가지 세부적으로 구현할 정보를 적어준다.

 


설명이 오늘은 전체적으로 길.. 예정이지만, 공식문서와 블로그들을 보면서 나 나름대로 정리하고 공부하는 거 같으니 머선 말인지 모르겠으면 그냥 코드부분만 봐도 될 것 같다.

 

 

 

 

코드 부분으로 ㄱㄱ 

 

models.py 

 

 

 

 

 

상속받을 장고의 기본 BaseUser 들 import 해주기.

 

 

 

길다 길어... 

장고 공식 문서 - 사용자 인증 커스텀 을 보고 어떠한 필드가 들어가야 하는지 옵션의 기능은 무엇인지 참고해서 맨 마지막 부분인 장고 공식 문서 - 사용자 모델 커스텀 full example  를 따왔다.

 

 

또한 기본 AbstractBaseUser 상속과 더불어 장고의 기본 그룹, 허가권 관리 기능을 재사용하는 PermissionsMixin 도 상속해주었다. 

 

 

위에 설명에서 말했듯이 기본 AbstractBaseUser를 상속하게 되면 몇가지 정해주어야 하는 세부사항이 있는데, 

내 프로젝트에선 이메일 , 닉네임을 입력받아야 하기 때문에 이 필드를 생성해주고, unique = True 옵션을 주어 사용자마다 다른 이메일, 닉네임을 주도록 옵션으로 설정했다.

verbose_name 은 옛날 포스팅에도 한번 언급했지만, 어드민 페이지에서 뜨는 것을 그냥 한글로 표현해주기 위해 설정한 옵션 ㅇㅇ.

 

나머지 like_post 는 좋아요 기능을 위한 필드 

 

korinkorin.tistory.com/29

 

2020.09.23_django_좋아요 기능 구현

2020.09.24_django_좋아요 기능 구현_정리노트 헣헣.. 며칠만의 포스팅인가..쥬륵 요즘 점점 하루에 하나 올릴만한 내 능력딸림...흑흑 오늘은 프로젝트 중에 좋아요 기능 구현! ㅠㅠ 드디어 원투원필

korinkorin.tistory.com

여기서 따로 포스팅 했기 때문에 이 기능에 대한 것은 생략한다.

 

date_joined 와 last_logined 등은 말그대로 사용자가 가입한 날짜와 마지막으로 로그인한 시간 필드. 

이 옵션들을 사용해주면, 나중에 다른모델에서 datetimfield를 사용할때의 시간과 충돌할 경우가 생길 수도 있는데, 그 충돌을 방지해줄수 있다고 한다.

date_joined 은 최초로 갱신한 날짜만 보여주기 위해 auto_now_add 옵션을,

last_logined 은 사용자가 들어올 때마다의 시간을 업뎃하기 위해 auto_now 으로 각각 설정해주었다.

 

 

 

 

자자 하지만 우리가 봐야할 것들은 사용자에게 입력받는 필드인 이메일과, 닉네임 부분 필드만 중점으로 보자!! 

 

 

이 필드들은 각각

USERNAME_FIELD 와 REQUIRED_FIELDS 로 적어 놨는데, 해석해보자면,

 

USERNAME_FIELD

이 필드는 유저의 고유 식별자로 사용되는 필드이다. 나는 여기서 이메일로 설정했다.

admin에 별다른 기능 없이 유저를 등록하게 되면 유저의 이름이 이메일로 표시되서 나타날 것이고, 우리가 뷰에서 request.user 를 불러온다면 그 유저또한 이메일 필드로 불러와진다!! 

이 필드는 유저 하나하나 고유의 필드이므로 unique = True 로 옵션을 주어야함.

 

 

admin 화면, 위에는 학교 이메일이라 가렸음 쨋든 이메일이 뜸

 

 

views.py 에서 print user

 

위에 사진들에서 보면 어드민에서도 이메일로 유저가 뜨고, 뷰 딴에서 user 를 프린트해서 찍어보면 터미널에 이메일이 찍히는 것을 볼 수 있음.

 

필드 이름대로 사용자 고유의 이름 필드라고 보면 된다!

 

 

REQUIRED_FIELDS 

말그대로 필수적으로 요구되는 필드. 이 필드는 장고에서 superuser가 사용자를 만드는 것과 같이 다른 부분에는 영향을 미치지는 않지만, 사용자를 만들때 이 필드를 입력해주세요 라는 메세지가 표시된다. 

 

한가지 주의할 점은, 이 필드의 메세지는 항상 표시되기 때문에, 비밀번호나, USERNAME_FIELDS 에 있는 것을 포함해서는 안된다.

 

 

 

전부 설명했다고 생각하지만, 아니지 

맨 위의 줄을 보면,

 

 objects = UserManager()

 

 

is_active = models.BooleanField(default=True)    

is_admin = models.BooleanField(default=False)    

is_superuser = models.BooleanField(default=False)    

is_staff = models.BooleanField(default=False)  

 

가 있다. 

 

 

우리가 유저만 이렇게 커스텀 해서 생성하면 그냥 되는 것이 아니라 , 유저를 생성할 때의 방법을 적어주어야 한다. 

그것이 바로 usermanager 다. 우리는 지금 내가 커스텀한 UserManager를 상속받아 그 방법대로 CommunityUser 를 생성한 것이다. 

 

 

CommunityUser 위에 상속받을 UserManager 모델을 작성해줍씨다.

 

 

 

먼저 장고에서 제공되는 BaseUserManager 를 상속받아서 커스텀해주었음.

 

또한 우리가 User를 커스텀해주었기 때문에 그에 맞는 UserManager 도 필수로 커스텀해야하는 부분이 있는데, 

create_user 함수와 , create_superuser 부분이다. 한줄 한줄 해석 해보게쑴.

 

 

use_in_migrations = True 

해당 옵션은 선택적으로 관리자를 마이그레이션으로 직렬화하는 명령어.. 라는데 이해한대로라면 superuser와 일반 user를 같은 선상에서 관리 할 수 있다는 말이 아닐까싶다 . ( 위키백과를 보니 그런 느낌인듯...? )

 

 

 

create_user 

create_user() 에서 안에 들어갈 인수들의 값은 우리가 필수로 입력받아야할 값들과 self, password=None 이 들어가야 한다. 나는 여기서 유저네임필드인 이메일과 닉네임을 넣어주어야 한다.

일반 유저들을 생성하는 방법으로, 이메일을 필수로 입력받기 위해 이메일을 입력하지 않으면 Valueerror를 띄워주고,

 

 

user.is_admin = False      

user.is_superuser = False      

user.is_staff = False

user.is_active = True   

 

 

이렇게 옵션을 준다. 

 

이 옵션들이 필요한 이유는, 커스텀 모델이 유저관리자와 함께 작동하려면 몇 가지 추가 속성 및 메서드를 정의 해야 하기 때문이다. 이러한 옵션들을 통해 관리자는 유저들의 접근을 제어할 수 있다.

이 유저는 일반 유저기 때문에 user.is_admin = False 을 통해 어드민 접근을 False 시키고,

user.is_superuser =False superuser 또한 아니기 때문에 False,

user.is_staff =False 는 어드민 페이지의 접근 권한이므로 또한 False.

마지막으로 user.is_active =True 는 유저를 활성화 시킬 것인지에 대한 옵션이다.

이메일 인증을 만약 한다면 False로 설정해두고, view 딴에서 일련의 과정을 통해 True로 주는 방법 또한 있겠지만, 나는 일단 True로 주고, 커스텀을 시작해서 이메일 인증시에는 따로 False처리를 할 예정이다.

 

 

마지막으로 유저의 비밀번호 값은 보안에 중요한 요소이므로, 해시값으로 저장해준다. 

db에 저장해주고 유저를 리턴해주면 끝!

 

create_superuser

슈퍼유저 생성도 똑같이 인수를 받아와 주고, 유저를 생성하는 방법으로 슈퍼유저를 생성해준다.

create_user 와 다른 점은 역시 모든 관리자 권한을 주어야 하기 때문에 

user.is_admin = True  

user.is_superuser = True      

user.is_staff = True  

user.is_active = True  

 

이 옵션들을 모두 True로 주면 된다.

이렇게 superuser도 db에 저장해주고 리턴하면 끝!!!!!!

 

이렇게 정의한 유저매니저를 유저모델에서

 

objects = UserManager()

 

라는 것을 통해 우리가 사용할 매니저는 위에서 커스텀해준 UserManger입니다 . 라고 지정해주는 것이다.

 

 

 

이렇게 AbstractBaseUser를 상속받아 커스텀 해주면, 장고에서 제공하는 유저크리에이션폼과 여러가지 폼들과 호환되기 때문에 유저모델폼 커스텀 또한 수월해진다. (AuthenticationForm, SetPasswordForm, PasswordChangeForm, AdminPasswordChangeForm ) 

 

 

 

마지막으로!! settings.py 로 가서!!!!

 

 

 

AUTH_USER_MODEL 옵션을 우리가 커스텀한 유저 경로로 바꿔주면 된다.

 

나중에 커스텀폼이나 여러가지 기능을 쓰려면 앱이름은 accounts로 하는 것이 편함 ㅇㅇ account로 했다가 고생한 1인...ㅎ.. 


 

줄줄줄 설명해놓았지만, 필드나 옵션들의 이름이 직관적이여서 찬찬히 살펴보면, 뜻들은 이해하는데 어렵진 않았지만, 필수적으로 요구되는 것들이 많아서 잘 참고하면서 커스텀해야할 것 같다. 

 

정리해서 과정을 살펴보자면, 

 

BaseUserManger상속하여, 유저를 생성할 때 사용하는 방법을 정의하는 UserManger커스텀하고,

AbstractBaseUser상속하여, 유저를 생성하는 CommunityUser커스텀 하였다.

 

 

 


 

오늘도 포스팅 절구절구... 다음에는 커스텀한 모델을 사용하여 , custom user form 으로 돌아오겠음 

 

오늘 포스팅 끝끝!

 

 

 

 

댓글