Django QuerySet查詢集原理及代碼實例

 更新時間:2020-06-14 04:45:23   作者:佚名   我要評論(0)

一 概念


Django的ORM中存在查詢集的概念。
查詢集,也稱查詢結果集、QuerySet,表示從數據庫中獲取的對象集合。
當調用如下過濾器方法時,Django會返回查詢集(而

一 概念

Django的ORM中存在查詢集的概念。

查詢集,也稱查詢結果集、QuerySet,表示從數據庫中獲取的對象集合。

當調用如下過濾器方法時,Django會返回查詢集(而不是簡單的列表):

  • all():返回所有數據。
  • filter():返回滿足條件的數據。
  • exclude():返回滿足條件之外的數據。
  • order_by():對結果進行排序。

對查詢集可以再次調用過濾器進行過濾,也就意味著查詢集可以含有零個、一個或多個過濾器。過濾器基于所給的參數限制查詢的結果。

從SQL的角度講,查詢集與select語句等價,過濾器像where、limit、order by子句。

二 兩大特性

1)惰性執行

  創建查詢集不會訪問數據庫,直到調用數據時,才會訪問數據庫,調用數據的情況包括迭代、序列化、與if合用

  例如,當執行如下語句時,并未進行數據庫查詢,只是創建了一個查詢集qs

# 查詢BookInfo模型類中的所有數據
qs = BookInfo.objects.all() 
# 繼續執行遍歷迭代操作后,才真正的進行了數據庫的查詢
for book in qs:
  print(book.btitle)

2)緩存

  使用同一個查詢集,第一次使用時會發生數據庫的查詢,然后Django會把結果緩存下來,再次使用這個查詢集時會使用緩存的數據,減少了數據庫的查詢次數。

  情況一:如下是兩個查詢集,無法重用緩存,每次查詢都會與數據庫進行一次交互,增加了數據庫的負載。

from booktest.models import BookInfo
# 每個列表內都為一個獨立的查詢集,兩次查詢集之間如果有數據插入,可能數據集會不同
[book.id for book in BookInfo.objects.all()]

[book.id for book in BookInfo.objects.all()]

  情況二:經過存儲后,可以重用查詢集,第二次使用緩存中的數據。

# 首先獲得一個查詢集
qs=BookInfo.objects.all()

# 第一次讀取數據,會查詢數據庫,然后增加緩存
[book.id for book in qs]
# 第二次讀取數據,直接查詢緩存
[book.id for book in qs]

3)何時查詢集不會被緩存?

  查詢集不會永遠緩存它們的結果。當只對查詢集的部分進行求值時會檢查緩存, 如果這個部分不在緩存中,那么接下來查詢返回的記錄都將不會被緩存。所以,這意味著使用切片或索引來限制查詢集將不會填充緩存。

  情況一:重復獲取查詢集對象中一個特定的索引將每次都查詢數據庫:

queryset = BookInfo.objects.all()

queryset[5] # 查詢數據庫
queryset[5] # 再一次查詢數據庫

  情況二:如果已經對全部查詢集求值過,則將檢查緩存:  

# 獲取查詢集
queryset = BookInfo.objects.all()
[entry for entry in queryset] # 查詢數據庫
print queryset[5] # 使用緩存 
print queryset[5] # 使用緩存 

   情況三:下面是一些其它例子,它們會使得全部的查詢集被求值并填充到緩存中:

# 獲取查詢集
queryset = BookInfo.objects.all()
[entry for entry in queryset]
bool(queryset)
entry in queryset
list(queryset)

  注:簡單地打印查詢集不會填充緩存。  

queryResult=models.Article.objects.all()
print(queryResult) # 查詢數據庫
print(queryResult) # 查詢數據庫 

三 限制查詢集

  1)、可以對查詢集進行取下標或切片操作,等同于sql中的limit和offset子句。

注意:不支持負數索引。
  對查詢集進行切片后返回一個新的查詢集,不會立即執行查詢。

  如果獲取一個對象,直接使用[0],等同于[0:1].get(),但是如果沒有數據,[0]引發IndexError異常,[0:1].get()如果沒有數據引發DoesNotExist異常。

  示例:獲取第1、2項,運行查看。

qs = BookInfo.objects.all()[0:2]

  2)、exists()方法:判斷某一個查詢集中是否有數據:

  簡單的使用if語句進行判斷也會完全執行整個queryset并且把數據放入cache,雖然你并不需要這些 數據!為了避免這個,可以用exists()方法,判斷查詢集中是否有數據,如果有則返回True,沒有則返回False。

if queryResult.exists():
#SELECT (1) AS "a" FROM "blog_article" LIMIT 1; args=()
print("exists...")

  3)、terator()方法: 來獲取數據,處理完數據就將其丟棄。

  當queryset非常巨大時,cache會成為問題。

  處理成千上萬的記錄時,將它們一次裝入內存是很浪費的。更糟糕的是,巨大的queryset可能會鎖住系統 進程,讓你的程序瀕臨崩潰。要避免在遍歷數據的同時產生queryset cache,可以使用iterator()方法 來獲取數據,處理完數據就將其丟棄。

objs = BookInfo.objects.all().iterator()
# iterator()可以一次只從數據庫獲取少量數據,這樣可以節省內存
for obj in objs:
  print(obj.title)
#BUT,再次遍歷沒有打印,因為迭代器已經在上一次遍歷(next)到最后一次了,沒得遍歷了
for obj in objs:
  print(obj.title)

  注:(1) 使用iterator()方法來防止生成cache,意味著遍歷同一個queryset時會重復執行查詢。所以使 #用iterator()的時候要當心,確保你的代碼在操作一個大的queryset時沒有重復執行查詢。

    (2) queryset的cache是用于減少程序對數據庫的查詢,在通常的使用下會保證只有在需要的時候才會查詢數據庫。 使用exists()和iterator()方法可以優化程序對內存的使用。不過,由于它們并不會生成queryset cache,可能 會造成額外的數據庫查詢。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:

  • django queryset 去重 .distinct()說明
  • Python的Django框架實現數據庫查詢(不返回QuerySet的方法)
  • Django ValuesQuerySet轉json方式
  • Django框架 querySet功能解析
  • django 中QuerySet特性功能詳解
  • python實現合并多個list及合并多個django QuerySet的方法示例
  • 介紹Python的Django框架中的QuerySets
  • Python的Django框架中的select_related函數對QuerySet 查詢的優化

相關文章

  • Django QuerySet查詢集原理及代碼實例

    Django QuerySet查詢集原理及代碼實例

    一 概念 Django的ORM中存在查詢集的概念。 查詢集,也稱查詢結果集、QuerySet,表示從數據庫中獲取的對象集合。 當調用如下過濾器方法時,Django會返回查詢集(而
    2020-06-14
  • Python Django中間件使用原理及流程分析

    Python Django中間件使用原理及流程分析

    一、什么是Django中間件   Django 中間件是用來處理Django的請求request和響應response的框架級別的鉤子,它是一個輕量,低級別的插件系統,用于全局范圍內改變
    2020-06-14
  • Pandas缺失值2種處理方式代碼實例

    Pandas缺失值2種處理方式代碼實例

    處理方式: 存在缺失值nan,并且是np.nan: 刪除存在缺失值的:dropna(axis='rows') 替換缺失值:fillna(df[].mean(), inplace=True) 不是缺失值nan,有默認標
    2020-06-14
  • php獲取小程序碼的實現代碼(B類接口)

    php獲取小程序碼的實現代碼(B類接口)

    效果圖 生成小程序碼的php代碼 public function qrcode(){ $member_id = session('id'); if(empty($member_id)) $this->error('請先登錄'); //推廣
    2020-06-14
  • PyInstaller運行原理及常用操作詳解

    PyInstaller運行原理及常用操作詳解

    pyinstaller 屬于Python第三方庫,使用前需先安裝 # 首先安裝pyinstaller pip install pyinstaller PyInstaller生成可執行程序 # PyInstaller 工具的命
    2020-06-14
  • Python輕量級web框架bottle使用方法解析

    Python輕量級web框架bottle使用方法解析

    Bottle是一個輕量級的Web框架,此框架只由一個 bottle.py 文件構成,不依賴任何第三方模塊。 #!/usr/bin/env python # -*- coding:utf-8 -*- from bottle import
    2020-06-14
  • Python xpath表達式如何實現數據處理

    Python xpath表達式如何實現數據處理

    xpath表達式 1. xpath語法 <bookstore> <book> <title lang="eng">Harry Potter</title> <price>999</price> </book> <book> <title lang="eng">Learning X
    2020-06-14
  • Python Django搭建網站流程圖解

    Python Django搭建網站流程圖解

    1. 創建Django REST framework工程 1.1手動創建工程文件夾 1.2進去工程文件夾內,執行命令:django-admin startproject web_project創建工程目錄 1.3修改,添加目錄
    2020-06-14
  • 簡單了解Spring Web相關模塊運行原理

    簡單了解Spring Web相關模塊運行原理

    Spring 的Web層中有4個模塊,分別為spring-web, spring-webmvc, spring-websocket 和 spring-webmvc-portlet。 spring-web spring-web 提供了核心的Web相關功能的
    2020-06-14
  • python如何更新包

    python如何更新包

    Python安裝新包,pip是很好用的安裝工具。 pip list 可以查詢所有已安裝的包和版本。怎么知道本地安裝包的版本是否有可以更新的新版本呢?通過pip list函數可以實現
    2020-06-14

最新評論

买宝宝用品赚钱吗 北京快中彩基本走势 安徽十一选五最大遗漏一定牛 幸运赛车2019开奖结果 湖北11选5开奖推荐号码 快乐双彩复式中奖计算器 越南河内五分彩开奖软件下载 如何打百家乐 加拿大快乐8预测开奖 幸运飞艇是骗局新闻 海南4+1怎么玩法 江苏快三遗漏天数 一定牛上海11选5预测 上海时时乐中彩网 广西快乐双彩走势图dun 股票涨跌的原理 举例 今天山西快乐十分走势图