상위 쿼리에서
prefetch_related
,select_related
적용 후 하위 쿼리에서 해당 인스턴스를 참조할 때 실재로 DB에 접근하지 않고 불러오는지 확인해보자.
지정된 쿼리셋을 미리 가져와서 데이터베이스 접근을 최소화할 수 있다.
select_related
와 차이점
- select_related : 데이터베이스에서 조인해서 가져오기때문에 복잡성을 방지하기 위해 foriegnkey와 onetoonefield에서만 제공
- prefetch_related : 해당 관계들에 대해 각각 조회하고 python에서 조인을 수행 → manytomany 와 manytoone 관계에서도 가능
- 예시 코드
class Restaurant(models.Model): pizzas = models.ManyToManyField(Pizza, related_name='restaurants') best_pizza = models.ForeignKey(Pizza, related_name='championed_by', on_delete=models.CASCADE) Restaurant.objects.prefetch_related('pizzas__toppings') Restaurant.objects.prefetch_related('best_pizza__toppings') Restaurant.objects.select_related('best_pizza').prefetch_related('best_pizza__toppings')
실행 중에 발생하는 이벤트나 상황들을 기록하는 데이터
- settings.py에 로깅 설정 추가
# (djang_project)/settings.py LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', } }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'level': 'DEBUG', }, } }
- handlers
- 로거의 각 메시지에 발생하는 작업을 결정하는 엔진
- 로깅 동작을 설명
- loggers
- 로깅 시스템의 진입점
- django.db.backends
- 데이터베이스와 코드의 상호 작용과 관련된 메시지
- DEBUG 단계에서만 생성됨
할일 목록을 가져와서 할일 개체의 유저들에게 접근
1) 적용안할 때
: todo.user에 접근할 때마다 query발생
todo_list = Todo.objects.all() for todo in todo_list: print(todo.user)
2) 적용할 때
: 첫 todo_list를 불러올 때만 query 발생
todo_list = Todo.objects.prefetch_related("user") print("====== test ======") for todo in todo_list: print(todo.user)