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
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는 자동으로 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 등이 있다.