django-orm-select_related()函數


一:介紹

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()。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM