select_related, prefetch_related, ManytoManyField
Models.py
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=300)
def __str__(self):
return self.name
class Book(models.Model):
name = models.CharField(max_length=300)
price = models.IntegerField(default=0)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
class Meta:
default_related_name = 'books'
def __str__(self):
return self.name
class Store(models.Model):
name = models.CharField(max_length=300)
books = models.ManyToManyField(Book)
class Meta:
default_related_name = 'stores'
def __str__(self):
return self.name
select_related(정참조)효과
def book_list():
queryset = Book.objects.all()
books = []
for book in queryset:
books.append({'id': book.id, 'name': book.name, 'publisher': book.publisher.name})
return books
Function : book_list
Number of Queries : 101
Finished in : 0.08s
def book_list_select_related():
queryset = Book.objects.select_related('publisher').all()
books = []
for book in queryset:
books.append({'id': book.id, 'name': book.name, 'publisher': book.publisher.name})
return books
Function : book_list
Number of Queries : 101
Finished in : 0.08s
prefetch_related(역참조)효과
@query_debugger
def store_list():
queryset = Store.objects.all()
stores = []
for store in queryset:
books = [book.name for book in store.books.all()]
stores.append({'id': store.id, 'name': store.name, 'books': books})
return stores
Function : store_list
Number of Queries : 11
Finished in : 0.02s
@query_debugger
def store_list_prefetch_related():
queryset = Store.objects.prefetch_related('books')
stores = []
for store in queryset:
books = [book.name for book in store.books.all()]
stores.append({'id': store.id, 'name': store.name, 'books': books})
return stores
Function : store_list_expensive_books_prefetch_related
Number of Queries : 12
Finished in : 0.05s
def book_list():
queryset = Book.objects.all()
books = []
for book in queryset:
books.append({'id': book.id, 'name': book.name, 'publisher': book.publisher.name})
return books
Function : book_list
Number of Queries : 101
Finished in : 0.08s
def book_list_select_related():
queryset = Book.objects.select_related('publisher').all()
books = []
for book in queryset:
books.append({'id': book.id, 'name': book.name, 'publisher': book.publisher.name})
return books
Function : book_list
Number of Queries : 101
Finished in : 0.08s
@query_debugger
def store_list():
queryset = Store.objects.all()
stores = []
for store in queryset:
books = [book.name for book in store.books.all()]
stores.append({'id': store.id, 'name': store.name, 'books': books})
return stores
Function : store_list
Number of Queries : 11
Finished in : 0.02s
@query_debugger
def store_list_prefetch_related():
queryset = Store.objects.prefetch_related('books')
stores = []
for store in queryset:
books = [book.name for book in store.books.all()]
stores.append({'id': store.id, 'name': store.name, 'books': books})
return stores
Function : store_list_expensive_books_prefetch_related
Number of Queries : 12
Finished in : 0.05s
fetch -> SQL query 문
Model.objects
.filter(조건절)
.select_related('정방향_참조_필드') # 해당 필드를 join해서 가져온다.
.prefetch_related('역방향_참조_필드') # 해당 필드는 추가쿼리로 가져온다.
select * from 'Model' m
(inner OR left outer) join '정방향_참조_필드' r on m.r_id=r.id
'where '조건절';
select * from '역방향_참조_필드' where id in ('첫번째 쿼리 결과의 id 리스트');
Manytomanyfield through
Manytomanyfield는 자동으로 middletable을 만들어준다.
수동으로 그 model class를 정의하고 싶을때 through를 사용한다.
Book모델에 Tag가 붙은 시기를 알고싶을때
class Tag(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
tags = models.ManyToManyField(Tag, through='BookTag')
class BookTag(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = '생성된 ManyToMany Table 이름'
modelsfield.through 하면 해당 필드의 manytomanyfield 중간 table객체에 접근
field는 id, from_id, to_id 등이 있다.
Author And Source
이 문제에 관하여(select_related, prefetch_related, ManytoManyField), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@eaa0305/selectrelated-prefetchrelated-ManytoManyField저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)