from django.db import connection from django.http import HttpResponse from .models import Article, Book, BookOrder def index4(request): # 1. select_related()想要获取与Book表经过外键的形式相关联的Author表中的数据 # 能够经过select_related()将相关联的表中的数据提取到内存中,减小到数据库中的查询 books = Book.objects.select_related('author') for book in books: print("%s, %s" % (book.author.name, book.author.age)) print(connection.queries) # 最后django底层能够执行一条sql语句就将全部的查询操做完成
django底层执行的sql语句为:python
[{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'},
{'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
{'sql': 'SELECT book
.id
, book
.name
, book
.pages
, book
.price
, book
.rating
, book
.author_id
, book
.publisher_id
, book
.score
, author
.id
, author
.name
, author
.age
, author
.email
FROM book
INNER JOIN author
ON (book
.author_id
= author
.id
)', 'time': '0.016'}]sql
books = Book.objects.all() # 采用all()方法获取每一个book的信息,而后向数据库中提出查询操做每一个book进行一次数据库的查询,提取出name,age字段的值 for book in books: print("%s,%s" % (book.author.name, book.author.age)) print(connection.queries)
django底层执行的sql语句为:
[{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'},
{'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
{'sql': 'SELECT book
.id
, book
.name
, book
.pages
, book
.price
, book
.rating
, book
.author_id
, book
.publisher_id
, book
.score
FROM book
', 'time': '0.000'},
{'sql': 'SELECT author
.id
, author
.name
, author
.age
, author
.email
FROM author
WHERE author
.id
= 5 LIMIT 21', 'time': '0.000'},
{'sql': 'SELECT author
.id
, author
.name
, author
.age
, author
.email
FROM author
WHERE author
.id
= 1 LIMIT 21', 'time': '0.000'},
{'sql': 'SELECT author
.id
, author
.name
, author
.age
, author
.email
FROM author
WHERE author
.id
= 4 LIMIT 21', 'time': '0.000'},
{'sql': 'SELECT author
.id
, author
.name
, author
.age
, author
.email
FROM author
WHERE author
.id
= 3 LIMIT 21', 'time': '0.000'}]数据库
def index(request): # 3. prefetch_related()能够对多对多,多对一的关联模型操做 # 好比,求每一个书的订阅量 # 返回的books中的是包裹在QuerySet中的book对象 books = Book.objects.prefetch_related('bookorder_set') print(type(books)) # <class 'django.db.models.query.QuerySet'> for book in books: print(type(book)) # <class 'front.models.Book'>, 以后就能够对返回的每一本书上的属性进行操做 # 如下咱们能够提取出每本书上的全部订单信息 # 注意:若是已经使用prefetch_related()进行了相关的查找,这里就不要使用filter()或者是其余的能够返回QuerySet的任何操做了。 # book_nums = book.bookorder_set.filter(price__gte=80) # 这里可使用all()方法进行获取。若是对bookorder再次进行了查询就会增长n个查询语句,下降查询的效率 book_nums = book.bookorder_set.all() for book_num in book_nums: print("%s, %s, %s" % (book_num.book.name, book_num.price, book_num.id)) print(connection.queries) return HttpResponse("success!")
django底层执行的sql语句为:django
[{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'},
{'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
{'sql': 'SELECT book
.id
, book
.name
, book
.pages
, book
.price
, book
.rating
, book
.author_id
, book
.publisher_id
, book
.score
FROM book
', 'time': '0.000'},
{'sql': 'SELECT book_order
.id
, book_order
.book_id
, book_order
.price
, book_order
.time
FROM book_order
WHERE book_order
.book_id
IN (1, 2, 3, 4)', 'time': '0.000'}]函数
总结:在多对多,多对一关联对象中执行查询操做,可使用prefetch_related()进行相关查询,这种方式中能够大大减小执行的sql语句,而且这种方式会产生两条查询语句。一样也可使用prefetch_related()对一对多或者是一对一的关联对象进行相关查询,一样也会在底层执行两条sql语句,若是使用select_related()进行查询的话只会执行一条查询语句。因此说若是是对一对一或者是一对多关联对象执行操做的话,建议使用select_related(); 若是是多对一或者是多对多关联模型执行操做时,就能够采用prefetch_related()fetch
def index(request): # 4. 使用传统的方法对多对多或者是多对一的关联模型表进行查询操做 books = Book.objects.all() for book in books: print(type(book)) # # <class 'front.models.Book'> book_nums = book.bookorder_set.all() for book_num in book_nums: print(type(book_num)) # # <class 'front.models.BookOrder'> print("%s, %s, %s" % (book_num.book.name, book_num.price, book_num.id)) print(connection.queries) return HttpResponse("success")
django底层执行的sql语句:
[{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'},
{'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
{'sql': 'SELECT book
.id
, book
.name
, book
.pages
, book
.price
, book
.rating
, book
.author_id
, book
.publisher_id
, book
.score
FROM book
', 'time': '0.000'},
{'sql': 'SELECT book_order
.id
, book_order
.book_id
, book_order
.price
, book_order
.time
FROM book_order
WHERE book_order
.book_id
= 1', 'time': '0.000'},
{'sql': 'SELECT book_order
.id
, book_order
.book_id
, book_order
.price
, book_order
.time
FROM book_order
WHERE book_order
.book_id
= 2', 'time': '0.000'},
{'sql': 'SELECT book_order
.id
, book_order
.book_id
, book_order
.price
, book_order
.time
FROM book_order
WHERE book_order
.book_id
= 3', 'time': '0.000'},
{'sql': 'SELECT book_order
.id
, book_order
.book_id
, book_order
.price
, book_order
.time
FROM book_order
WHERE book_order
.book_id
= 4', 'time': '0.016'}]code
def index5(request): # 5.若是确实要对预先查询的结果,再进行一些操做的话,可使用Prefetch()函数 # 能够将要进行的操做赋值给Prefetch函数中的queryset参数 prefetch = Prefetch('bookorder_set', queryset=BookOrder.objects.filter(price__gte=90)) books = Book.objects.prefetch_related(prefetch) for book in books: # <class 'front.models.BookOrder'> orders = book.bookorder_set.all() for order in orders: print("%s, %s, %s" % (order.book.name, order.price, order.id)) print(connection.queries) return HttpResponse("success")
django底层执行的sql语句为:
水浒传, 95.0, 2
[{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'},
{'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
{'sql': 'SELECT book
.id
, book
.name
, book
.pages
, book
.price
, book
.rating
, book
.author_id
, book
.publisher_id
, book
.score
FROM book
', 'time': '0.000'},
{'sql': 'SELECT book_order
.id
, book_order
.book_id
, book_order
.price
, book_order
.time
FROM book_order
WHERE (book_order
.price
>= 90.0e0 AND book_order
.book_id
IN (1, 2, 3, 4))', 'time': '0.000'}]对象