장고 First argument to get_object_or_404() must be a Model, Manager, or QuerySet, not 'str' 에러 해결하기
오늘 장고 프로젝트를 진행하다가 조금 고생한 경험을 공유하고자 한다. 작업 중에 get_object_or_404() 함수를 사용할 때 이상한 에러 메시지를 마주쳤다. 에러 메시지는 다음과 같았다:
"First argument to get_object_or_404() must be a Model, Manager, or QuerySet, not 'str'"
처음에는 무슨 뜻인지 도통 이해가 가지 않았다. 이 함수는 주어진 쿼리셋에서 객체를 가져오거나, 객체가 없으면 404 오류를 반환해 주는 유용한 도우미 함수인데, 왜 문자열이 문제인지 의아했다.
문제의 원인
조사를 해보니 이 에러의 주된 원인은 settings.AUTH_USER_MODEL을 사용하는 것이었다. 이 설정 값은 커스텀 사용자 모델을 정의하기 위한 것이고, 문자열 형식으로 리턴되었다. 내가 사용한 코드는 대략 이러했다:
from django.shortcuts import get_object_or_404
from django.conf import settings
user = get_object_or_404(settings.AUTH_USER_MODEL, id=user_id)
이렇게 하니 settings.AUTH_USER_MODEL이 문자열로 반환되어 에러가 발생한 것이었다. 아하, 이제야 이해가 되었다!
이 문제를 해결하기 위해 두 가지 방법을 생각해 보았다.
방법 1: 커스텀 사용자 모델 직접 입력하기
첫 번째 방법은 커스텀 사용자 모델을 직접 참조하는 것이었다. 내 프로젝트에서 사용자 모델이 MyUser라는 이름이라면, 코드를 이렇게 수정할 수 있었다:
from django.shortcuts import get_object_or_404
from .models import MyUser # 커스텀 사용자 모델을 임포트합니다.
user = get_object_or_404(MyUser, id=user_id)
이렇게 하면 get_object_or_404()가 올바른 모델 객체를 받을 수 있어서, 에러를 피할 수 있었다.
방법 2: get_user_model() 사용하기
두 번째 방법은 Django의 내장 함수인 get_user_model()을 사용하는 것이었다. 이 함수는 현재 설정된 사용자 모델을 반환해 주기 때문에, 정말 편리했다. 코드는 이렇게 쓸 수 있었다:
from django.shortcuts import get_object_or_404
from django.contrib.auth import get_user_model
User = get_user_model() # 현재 설정된 사용자 모델을 가져옵니다.
user = get_object_or_404(User, id=user_id)
이 방법을 사용하면 나중에 커스텀 사용자 모델을 변경해도 코드를 수정할 필요가 없으므로, 훨씬 유연하게 대처할 수 있을 것 같다.
결국, Django에서 get_object_or_404()를 사용할 때는 첫 번째 인자로 문자열이 아닌 모델이나 쿼리셋을 전달해야 한다. settings.AUTH_USER_MODEL을 직접 사용하면 문자열로 반환되어 에러가 발생할 수 있으니, 커스텀 모델을 직접 입력하거나 get_user_model() 함수를 사용하는 것이 좋겠다.