prefetch_related를 적용했음에도 불구하고 계속 쿼리를 날립니다.
Opened this issue · 4 comments
queryset = Seminar.objects.prefetch_related('userSeminar').prefetch_related('userSeminar__user').order_by('-created_at')
위와 같이 쿼리셋을 가져왔음에도 불구하고
아래 부분에서 UserSeminar에 대한 쿼리를 계속 날립니다.
왜 그런건지, 해결 방법은 무엇인지 궁금합니다.
# views.py
def list(self, request):
seminars = self.get_queryset()
return Response(MiniSeminarSerializer(seminars, many=True).data)
# serializers.py
def get_participants_count(self, seminar):
return seminar.userSeminar.filter(role='participant').count()
자답합니다.
맨 처음 queryset을 가져올 때, django.db.models.Prefetch
을 통해 prefetch_related로 가져오는 object list를 가져와 저장해둘 수 있습니다. 아래와 같이 사용합니다.
Prefetch(<related name> , queryset = <object들을 가져오는 queryset> , to_attr = <저장할 이름>)
ex)
from django.db.models import Prefetch
...
queryset = Seminar.objects.prefetch_related(
Prefetch( 'userSeminar', queryset = UserSeminar.objects.select_related('seminar'), to_attr = 'seminar_userSeminar')
)
그럼 아래처럼 serializers.py에서도 사용이 가능합니다.
seminar.seminar_userSeminar
다만 queryset으로 가져오는 게 아니라 list로 가져옵니다.
따라서 queryset에서 사용할 수 있는 method를 list에 대해 직접 정의해서 써야 합니다.
왜 Prefetch 없이는 안되는지는 모르겠습니다! 알게되면 붙이겠습니다 ㅎㅎ
이때 queryset = UserSeminar.objects.select_related('seminar')
옵션을 추가하신 이유는 무엇인가요?
Seminar.objects.all()
을 가져오면 seminar에 대한 정보가 이미 있을텐데, prefetch에서 seminar를 다시 join하면 정보가 중복해서 받아지지 않나요?