Django 프로젝트의 User 모델을 확장하여 사용하고자 AbstractUser 모델을 상속받은 새 모델을 추가하여 마이그레이션을 생성하고 migrate를 진행, 아래와 같은 ValueError 발생
Traceback (most recent call last):
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/manage.py", line 22, in <module>
main()
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
utility.execute()
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/venv/lib/python3.10/site-packages/django/core/management/base.py", line 402, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/venv/lib/python3.10/site-packages/django/core/management/base.py", line 448, in execute
output = self.handle(*args, **options)
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/venv/lib/python3.10/site-packages/django/core/management/base.py", line 96, in wrapped
res = handle_func(*args, **kwargs)
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/venv/lib/python3.10/site-packages/django/core/management/commands/migrate.py", line 295, in handle
pre_migrate_apps = pre_migrate_state.apps
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/venv/lib/python3.10/site-packages/django/utils/functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/venv/lib/python3.10/site-packages/django/db/migrations/state.py", line 566, in apps
return StateApps(self.real_apps, self.models)
File "/Users/cjy/Desktop/Source/Workspace/lagom_django/venv/lib/python3.10/site-packages/django/db/migrations/state.py", line 637, in __init__
raise ValueError("\n".join(error.msg for error in errors))
ValueError: The field admin.LogEntry.user was declared with a lazy reference to 'shortener.users', but app 'shortener' doesn't provide model 'users'.
로그인과 회원가입만 구현하려는 목적에 기존에 Django가 기본으로 제공하는 User모델 을 사용하였고 어떤 커스텀도 필요하지 않았다.
Django 프로젝트의 User모델 을 이용하여 로그인과 회원가입을 구현하는 도중 User모델에 Forignkey를 갖는 필드가 필요해졌다.
📌 처음 설계와는 다르게 로그인한 사용자를 기반으로 결제 기능 을 추가하고자 User 모델을 확장하는 것으로 설계를 수정하였다.
class PayPlan(models.Model):
name = models.CharField(max_length=20)
price = models.IntegerField()
updated_at = models.DateTimeField(auto_now=True)
create_at = models.DateTimeField(auto_now_add=True)
class Users(AbstractUser):
pay_plan = models.ForeignKey(PayPlan, on_delete=models.DO_NOTHING)
위의 코드와 같이 Users 모델이 AbstractUser 을 상속받게 한 후, 클레스 안에 'pay_plan'을 추가하여 Users 모델이 기존의 User 모델을 그대로 이용하며 새 필드만 가지는 모델로 사용할 수 있게 확장 코드를 작성하였다.
이렇게 코드 작성 후 DB 적용을 위해 마이그레이션을 진행하였지만 위와 같은 ValueError가 발생하였다.
Django에서의 User 모델의 확장 방법 중 AbstractUser 와 AbstractBaseUser 상속받아 확장하는 것은 중요한 조건이 필요했다.
그 조건은 Django가 첫 Users모델을 생성하기 전에 AbstractUser 또는 AbstractBaseUser 를 상속받는 모델이라 확정을 한 후 마이그레이션을 진행해야 한다는 것이다.
그 원인은 첫 마이그레이션을 진행하면 Django가 관여하고 관리하는 auth-user가 이미 생성이 되는데 그 이후에 생성된 User 모델을 변경하려고 충돌이 일어나기 때문이다.
물론 auth-user가 이미 생성이 된 후에도 변경이 가능하다지만 지금 수준에서는 다루기 어렵다고 판단하여 이런 상황이 나오지 않게 하려고 한다.
migrations폴더 안에 __init__.py폴더를 제외하고 모두 삭제한다.이 방법은 기존에 누적되어 있던 마이그레이션 파일을 최종 하나로만 마이그레이션 진행하는 방법이다.
그렇기 때문에 이 방법은 초기 개발 단계 또는 아직 운영하지 않은 단계 에서만 가능하다. 이미 운영중이거나 DB변경 내역이 중요한 단계에서는 할 수 없기 때문이다.
🫢 이미 DB에 필요한 데이터가 쌓여 있거나 DB 변경 내역이 필요하지 않다면 방법은 존재한다.
User 모델의 확장하는 방법이 필요한 경우 아래를 참고하자.
cjyooong.log - Django User Model
Django 정식 Docs