Django의 .values()
메서드는 QuerySet을 실행할 때 특정 필드만 선택하여 반환하는 기능을 합니다. 이 메서드를 사용하면 결과가 딕셔너리 목록 (list of dictionaries) 형태로 반환되며, 모든 모델 필드가 아닌 지정한 필드만 가져올 수 있습니다.
📌 주요 특징:
- 일반적인 QuerySet(
Model.objects.all()
)은 객체(Model 인스턴스) 리스트를 반환하지만,.values()
사용 시 딕셔너리 리스트(dict list)를 반환함.
🛠 1. 기본 사용법
from myapp.models import Post
# 기존 QuerySet (모든 필드를 포함한 모델 인스턴스 반환)
posts = Post.objects.all()
print(posts)
# , ]>
# .values() 사용 (title과 author 필드만 가져옴)
posts = Post.objects.values('title', 'author')
print(posts)
#
📌 차이점:
Post.objects.all()
→ Post 모델의 인스턴스 리스트 반환Post.objects.values('title', 'author')
→ 딕셔너리(dict) 리스트 반환
🛠 2. .values()
의 성능 최적화
.values()
를 사용하면 불필요한 필드 로딩을 방지하여 쿼리 성능을 향상시킬 수 있습니다. 즉, 필요한 필드만 가져오기 때문에 데이터베이스 부하가 감소합니다.
# 전체 모델 객체 가져오기 (비효율적)
Post.objects.all()
# 필요한 필드만 가져오기 (효율적)
Post.objects.values('title', 'author')
🛠 3. .values()
와 .values_list()
의 차이
✅ .values()
→ 딕셔너리(dict) 리스트 반환
Post.objects.values('id', 'title')
# <QuerySet [{'id': 1, 'title': '첫 번째 게시글'}, {'id': 2, 'title': '두 번째 게시글'}]>
✅ .values_list()
→ 튜플(tuple) 리스트 반환
Post.objects.values_list('id', 'title')
# <QuerySet [(1, '첫 번째 게시글'), (2, '두 번째 게시글')]>
🛠 4. .values()
와 annotate()
함께 사용하기
annotate()
와 .values()
를 함께 사용하면, 집계(aggregation)된 데이터를 딕셔너리 형태로 가져올 수 있습니다.
from django.db.models import Count
from myapp.models import Post, Comment
# 각 게시글(post)에 대한 댓글 개수를 가져오기
Post.objects.values('title').annotate(comment_count=Count('comments'))
🛠 5. .values()
를 사용한 필터링 (distinct()
와 함께 사용)
예제: 특정 author
가 작성한 모든 게시글의 제목을 가져오되, 중복을 제거하는 경우:
Post.objects.values('title').filter(author=1).distinct()
📌 결론
- ✅
.values()
는 QuerySet을 딕셔너리(dict) 리스트로 변환하여 특정 필드만 가져옴. - ✅ 불필요한 필드를 제외하여 쿼리 성능 최적화 가능.
- ✅
.values_list()
와 비교하면.values()
는 딕셔너리,.values_list()
는 튜플 반환. - ✅
.annotate()
와 함께 사용하여 집계 데이터를 딕셔너리 형태로 가져올 수 있음. - ✅
.distinct()
와 함께 사용하여 중복 제거 가능.
💡 .values()
는 데이터 조회 시 불필요한 필드를 줄여 성능을 최적화하는 강력한 기능! 🚀 사용 목적에 따라 모델 객체 대신 딕셔너리로 데이터를 가져와야 할 때 활용하면 매우 유용합니다! 😊
아! 위에서 예시의 결과를 보시고 이미 눈치 채신 분들도 있겠지만, .value(), .value_list() 를 통해 반환되는 딕셔너리 리스트들은 여전히 쿼리셋 입니다. (지연평가 되므로 즉시평가가 필요하신 분들은 list()로 감싸 주세요!)
Add a New Comment