一:介紹
select_related函數:
1 def select_related(self, *fields): 2 """ 3 Returns a new QuerySet instance that will select related objects. 4 5 If fields are specified, they must be ForeignKey fields and only those 6 related objects are included in the selection. 7 8 If select_related(None) is called, the list is cleared. 9 """ 10 11 if self._fields is not None: 12 raise TypeError("Cannot call select_related() after .values() or .values_list()") 13 14 obj = self._clone() 15 if fields == (None,): 16 obj.query.select_related = False 17 elif fields: 18 obj.query.add_select_related(fields) 19 else: 20 obj.query.select_related = True 21 return obj
使用該函數的,他的返回值是一個和他相關聯的對象新Queryset對象的集合。如果填寫第二個參數的話,他必須是外鍵關聯的對象。
有如下表結構:
1 from django.db import models 2 3 # Create your models here. 4 class Book(models.Model): 5 name=models.CharField(max_length=32) 6 author=models.ForeignKey('Author') 7 8 9 class Author(models.Model): 10 name=models.CharField(max_length=32)
簡單插入數據:
book表
author表:
select_related()函數:作用當我們在查詢帶有外鍵關聯的表的對象的時候,正常查詢是分2次查詢:
比如上面的表結構:查詢evil的對應的書籍。
1)首先我們在author表中查詢到evil的對象:author_obj=models.Author.objects.filter(name='evil')
2)通過這個evil對象查詢book對象:author_obj.book
如上是經過2次數據庫的查詢。而使用select_related函數的時候,只需查詢一次數據庫就可以獲得相應的關聯的(外鍵)的對象集合。
1 def check(request): 2 author=models.Author.objects.select_related().filter(name='evil').first() 3 book=author.book_set.all() 4 for i in book: 5 print(i.name) 6 return HttpResponse('ok')
select_related函數幫我們做了:在一次的查詢中查詢到對象集合以及和關聯的對象的集合。可以直接獲取相應的外鍵的對象列表。
在效率上比之前的分步查詢上,效率高,
前提:查詢的表和關聯的表的層級不深和不多。情況下:效率高;
如果查詢的表的層級比較多,關聯的表較多(外鍵較多),會耗時。
參數:depth,執行獲取關聯對象的深度,如果depth=2,不僅能查詢到作者關聯的實體對象,而且還可以查詢book關聯(外鍵)的實體對象。默認情況將會獲取到該作者的所有關聯對象的 包括關聯對象的子關聯對象。
所以用他有利有弊,主要看表的關聯復雜程度。
所以當我們獲取對象需要它相關聯的對象時,就請用select_related()吧,如果該對象關聯的表很多,請指定depth的值,避免資源的浪費;反之避免select_related()。