Django에서 모델의 choices 필드를 사용할 때, get_[field]_display()
메서드를 통해 쉽게 표시값을 가져올 수 있습니다. 하지만 .values()
를 사용하면 이 메서드가 동작하지 않는 상황이 발생합니다.
예를 들어, 다음과 같은 모델이 있다고 가정해보겠습니다:
class Notice(models.Model):
CATEGORY_CHOICES = (
('NOTICE', '공지'),
('EVENT', '이벤트'),
('NEWS', '뉴스'),
)
category = models.CharField(max_length=10, choices=CATEGORY_CHOICES)
일반적으로는 다음과 같이 사용할 수 있습니다:
notice = Notice.objects.first()
print(notice.get_category_display()) # '공지' 출력
하지만 .values()
를 사용하면:
notice = Notice.objects.values('category').first()
# notice.get_category_display() # AttributeError 발생!
.values()
는 모델 인스턴스가 아닌 딕셔너리를 반환합니다. 따라서 모델 인스턴스의 메서드인 get_[field]_display()
를 사용할 수 없게 됩니다.
가장 간단한 방법은 .values()
를 사용하지 않고 모델 인스턴스를 직접 사용하는 것입니다:
notices = Notice.objects.all()
for notice in notices:
print(notice.get_category_display())
성능상의 이유로 .values()
가 필요한 경우, annotate()
를 사용하여 display 값을 직접 추가할 수 있습니다:
from django.db.models import Case, When, Value, CharField
notices = Notice.objects.annotate(
category_display=Case(
*[When(category=k, then=Value(v)) for k, v in Notice.CATEGORY_CHOICES],
output_field=CharField(),
)
).values('category', 'category_display')
장점:
단점:
장점:
단점:
.values()
의 사용은 성능 최적화에 도움이 될 수 있지만, get_[field]_display()
와 같은 모델 메서드를 사용할 수 없다는 제한이 있습니다. 프로젝트의 요구사항과 성능 특성을 고려하여 적절한 방법을 선택하는 것이 중요합니다.