1번째 줄: |
1번째 줄: |
| [[분류:장고 기능구현(초급)]] | | [[분류:장고 기능구현(초급)]] |
| ==개요== | | ==개요== |
− | 기본적으로 제공되는 유저모델은 제한적이다. 학교에서 운영한다면 학번 등의 정보를 저정해야 하는데, 이처럼 제공하지 않는 기능들을 확장하는 과정이 필요하다.
| |
| | | |
− | 장고에서 기본적으로 제공해주는 항목을 넘어 개별항목을 지정하는 등의 작업을 하기 위해 처음부터 커스텀유저를 사용하길 권장한다. | + | === 시작에 앞서... === |
| + | # 프로젝트의 시작 전에 구현해야 한다. |
| + | #:- 기존에 가입된 회원들이 있는 상태에서 새로운 DB 테이블을 정의할 때, migrate 따위의 명령을 실행하면 <code>django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency 앱이름.0001_initial on database 'default'.</code> 같은 에러가 뜬다. 가장 간단한 해결법은 기존 DB를 삭제하고 다시 처음부터 설계를 반영하는 것이다. 때문에 이런 불상사를 막으려면 프로젝트를 제대로 시작하기 전에 최소한의 앱과 커스텀 유저는 구현해 두어야 한다. |
| + | #:- 만약 프로젝트의 중간에 추가해 넣어야 한다면 다음의 문서를 참고하자. [https://code.djangoproject.com/ticket/25313 링크.] 개빡센 여정이 예상된다. |
| + | |
| + | * 기본적으로 제공되는 유저모델은 제한적이다. 학교에서 운영한다면 학번 등의 정보를 저정해야 하는데, 이처럼 제공하지 않는 기능들을 확장하는 과정이 필요하다. |
| + | * 장고에서 기본적으로 제공해주는 항목을 넘어 개별항목을 지정하는 등의 작업을 하기 위해 처음부터 커스텀유저를 사용하길 권장한다. |
| + | * 일반적으로 본격적인 프로젝트를 시작하기 전에 만들기가 권장된다. 프로젝트 도중에 모델을 바꾸는 것은 DB의 왜래키나 다대다 관계에 영향을 미치는데, 이를 다시 고치는 일은 꽤 어려운 일이기 때문이다.(중간에 커스텀모델을 추가하는 경우엔 DB자체를 지우고, 다시 구성한다.) 장고의 의존성 특성 때문에 최초의 DB에 생성되어 포함되어야 한다. |
| {| class="wikitable" | | {| class="wikitable" |
| |+유저 기능을 확장하는 방법<ref>https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html</ref> | | |+유저 기능을 확장하는 방법<ref>https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html</ref> |
27번째 줄: |
33번째 줄: |
| | | |
| 기본 속성으로 id(기본키), password, last_login, is_superuser, username, first_name, last_name, email, is_staff, is_active, date_joined 필드가 들어있다. | | 기본 속성으로 id(기본키), password, last_login, is_superuser, username, first_name, last_name, email, is_staff, is_active, date_joined 필드가 들어있다. |
− | |}일반적으로 본격적인 프로젝트를 시작하기 전에 만들기가 권장된다. 프로젝트 도중에 모델을 바꾸는 것은 DB의 왜래키나 다대다 관계에 영향을 미치는데, 이를 다시 고치는 일은 꽤 어려운 일이기 때문이다.(중간에 커스텀모델을 추가하는 경우엔 DB자체를 지우고, 다시 구성한다.) 장고의 의존성 특성 때문에 최초의 DB에 생성되어 포함되어야 한다. | + | |} |
| ===사용하는 것은 AbstractBaseUser=== | | ===사용하는 것은 AbstractBaseUser=== |
| AbstractUser는 크게 변경하거나 확장하는 내용이 많지 않다.(그냥 Profile 방식을 사용해도 되지 않을까 싶을 정도로..) 하여, 여기에선 조금 어렵지만, 더 자유로운 BaseUser에 대해 다뤄보고자 한다. | | AbstractUser는 크게 변경하거나 확장하는 내용이 많지 않다.(그냥 Profile 방식을 사용해도 되지 않을까 싶을 정도로..) 하여, 여기에선 조금 어렵지만, 더 자유로운 BaseUser에 대해 다뤄보고자 한다. |
− |
| |
− | === 시작에 앞서... ===
| |
− |
| |
− | # 프로젝트의 시작 전에 구현해야 한다.
| |
− | #:- 기존에 가입된 회원들이 있는 상태에서 새로운 DB 테이블을 정의하는 것으로, migrate 따위의 명령을 실행하면 <code>django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency 앱이름.0001_initial on database 'default'.</code> 같은 에러가 뜬다. 가장 간단한 해결법은 기존 DB를 삭제하고 다시 처음부터 설계를 반영하는 것이다. 때문에 이런 불상사를 막으려면 프로젝트를 제대로 시작하기 전에 최소한의 앱과 유저는 구현해 두어야 한다.
| |
− | #:- 만약 프로젝트의 중간에 추가해 넣어야 한다면 다음의 문서를 참고하자. [https://code.djangoproject.com/ticket/25313 링크.] 개빡센 여정이 예상된다.
| |
| | | |
| ==사전작업== | | ==사전작업== |
− | 어떤 앱의 어떤 모델을 기본 유저로 사용할지 생각하고 진행한다. | + | 어떤 앱의 어떤 모델을 기본 유저로 사용할지 생각하고 진행한다.(그냥 앱을 새로 파는 게 적절하다.) |
| ==모델 작성== | | ==모델 작성== |
− | 필수적으로 2개의 모델을 작성해주어야 한다. BaseUserManager를 상속받은 모델과 AbstractBaseUser를 상속받은 모델.
| |
| | | |
− | 사람마다 짜는 방식이 달라서, 그리고 일일이 주석을 달아두지 않기 때문에 처음 하는 사람들은 해석하는 데 적잖이 애먹는다. | + | * 필수적으로 2개의 모델을 작성해주어야 한다. BaseUserManager를 상속받은 모델과 AbstractBaseUser를 상속받은 모델. |
| + | * 사람마다 짜는 방식이 달라서, 그리고 일일이 주석을 달아두지 않기 때문에 처음 하는 사람들은 해석하는 데 적잖이 애먹는다. |
| + | * 아래에선 계정 식별자를 identifier로 설정했는데, 장고에서 기본적으로 사용하는 username 필드를 사용하는 편이 좋다.(권한 관련 확장기능에서 username을 그대로 사용하는 경우가 많아, 계정 식별자는 username을 사용하는 편이 좋다.) |
| + | |
| {| class="wikitable" | | {| class="wikitable" |
| !과정 | | !과정 |
52번째 줄: |
54번째 줄: |
| |<syntaxhighlight lang="python"> | | |<syntaxhighlight lang="python"> |
| from django.db import models | | from django.db import models |
− | from django.contrib.auth.models import (BaseUserManager, AbstractBaseUser) | + | from django.contrib.auth.models import BaseUserManager, AbstractBaseUser |
| </syntaxhighlight> | | </syntaxhighlight> |
| |- | | |- |
58번째 줄: |
60번째 줄: |
| |유저를 생성할 때 사용하는 헬퍼. | | |유저를 생성할 때 사용하는 헬퍼. |
| AbstractBaseUser가 참고하니, 그보다 위에 작성되어야 한다. | | AbstractBaseUser가 참고하니, 그보다 위에 작성되어야 한다. |
| + | |
| | | |
| | | |
| 인수로 받는 email 등을 다른 것으로 바꿀 수 있다. | | 인수로 받는 email 등을 다른 것으로 바꿀 수 있다. |
| + | |
| | | |
| | | |
166번째 줄: |
170번째 줄: |
| | | |
| ===DB에 반영=== | | ===DB에 반영=== |
− | 이 작업을 처음에 하는 게 아니라, 개발 중에 하는 경우, 다른 앱의 모델에서 유저를 참조하고 있을 때 참조테이블로 User가 들어가 있는데, 이 때문에 'auth.User', which has been swapped out. 라는 에러가 뜬다. | + | 이 작업을 처음에 하는 게 아니라, 개발 중에 하는 경우, 다른 앱의 모델에서 유저를 참조하고 있을 때 참조 테이블로 User가 들어가 있는데, 이 때문에 'auth.User', which has been swapped out. 라는 에러가 뜬다. |
| | | |
| 이것과 from django.contrib.auth.models import User를 지우고, from django.conf import settings 후에 | | 이것과 from django.contrib.auth.models import User를 지우고, from django.conf import settings 후에 |
| | | |
− | User 대신 settings.AUTH_USER_MODEL를 넣어주면 된다. | + | User 대신 <code>settings.AUTH_USER_MODEL</code>를 넣어주면 된다. |
| + | |
| + | 위 <code>settings.AUTH_USER_MODEL</code>은 텍스트만 반환하기 때문에, 유저 객체 자체를 불러오고 싶다면 <code>from django.contrib.auth import get_user_model</code> 을 사용하면 된다. |
| ===settings.py에 만들 모델 추가=== | | ===settings.py에 만들 모델 추가=== |
− | 아래 작업은 DB 반영이 끝나 후에 진행해야 한다. 그렇지 않으면 ValueError: The field admin.LogEntry.user was declared with a lazy reference to 'account.user', but app 'account' isn't installed. 따위의 에러가 발생한다. | + | 아래 작업은 DB 반영이 끝나 후에 진행해야 한다. 그렇지 않으면 <code>ValueError: The field admin.LogEntry.user was declared with a lazy reference to 'account.user', but app 'account' isn't installed.</code> 따위의 에러가 발생한다. |
| | | |
− | 보통은 앱이름은 account, 모델이름은 User 따위가 된다.<syntaxhighlight lang="python">
| + | 다음과 같은 줄을 settings.py 내에 추가한다. |
− | AUTH_USER_MODEL = 'account.User' # 관리유저로 사용할 모델을 설정한다.
| |
| | | |
| + | 보통은 앱이름은 custom_account, 모델 이름은 User 따위가 된다.<syntaxhighlight lang="python"> |
| + | AUTH_USER_MODEL = 'custom_account.User' # 관리유저로 사용할 모델을 설정한다. |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
| === 중간 확인 === | | === 중간 확인 === |
| | | |
− | * python manage.py createsuperuser로 관리계정 생성. | + | * python manage.py createsuperuser로 관리 계정 생성. |
| * 사이트를 실행시킨 후 /admin에 들어가 로그인해본다. | | * 사이트를 실행시킨 후 /admin에 들어가 로그인해본다. |
| | | |
| ==관리자 화면에 등록== | | ==관리자 화면에 등록== |
− | admin.py를 작성한다.<syntaxhighlight lang="python"> | + | 아직 관리자 화면에선 가입한 유저들의 정보가 나오지 않는다. 이들을 한눈에 관리하기 위해 admin.py를 작성한다.<syntaxhighlight lang="python"> |
| from django.contrib import admin | | from django.contrib import admin |
| from .models import User # 직접 등록한 모델 | | from .models import User # 직접 등록한 모델 |
193번째 줄: |
200번째 줄: |
| list_display = ('identifier',) | | list_display = ('identifier',) |
| exclude = ('password',) # 사용자 상세 정보에서 비밀번호 필드를 노출하지 않음 | | exclude = ('password',) # 사용자 상세 정보에서 비밀번호 필드를 노출하지 않음 |
− | </syntaxhighlight>그럼 이제 이 모델로 계정관리가 가능해진다. | + | </syntaxhighlight>그럼 이제 이 모델로 계정 관리가 가능해진다. |
| | | |
| ==폼 작성== | | ==폼 작성== |