select_related, prefetch_related, ManytoManyField
Models.pyselect related(正を参照)効果
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.08sdef 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は自動的に中間テーブルを作成します.
そのモデルクラスを手動で定義する場合はthroughを使用します.
Bookモデルにマークされている時間を知りたい場合は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.完了すると、このフィールドのManytomanyfield中間テーブルオブジェクトにアクセスします.
fieldにはid、from id、to idなどがあります.
Reference
この問題について(select_related, prefetch_related, ManytoManyField), 我々は、より多くの情報をここで見つけました
https://velog.io/@eaa0305/selectrelated-prefetchrelated-ManytoManyField
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
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
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
@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_listNumber 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_relatedNumber 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は自動的に中間テーブルを作成します.
そのモデルクラスを手動で定義する場合はthroughを使用します.
Bookモデルにマークされている時間を知りたい場合は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.完了すると、このフィールドのManytomanyfield中間テーブルオブジェクトにアクセスします.
fieldにはid、from id、to idなどがあります.
Reference
この問題について(select_related, prefetch_related, ManytoManyField), 我々は、より多くの情報をここで見つけました
https://velog.io/@eaa0305/selectrelated-prefetchrelated-ManytoManyField
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
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 이름'
Reference
この問題について(select_related, prefetch_related, ManytoManyField), 我々は、より多くの情報をここで見つけました https://velog.io/@eaa0305/selectrelated-prefetchrelated-ManytoManyFieldテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol