添加測試數據
- 在SQLyog中執行
INSERT INTO app_bookinfo(title,bpub_date,bread,bcomment,isDelete) VALUES
('三國演義','1980-5-1',12,34,0),
('紅樓夢','1986-7-24',36,40,0),
('水滸傳','1995-12-24',20,80,0),
('西遊記','1987-11-11',58,24,0);
INSERT INTO app_personinfo(pname,pgender,pcomment,isDelete) VALUES
('曹操',1,'字孟德',0),
('劉備',1,'字玄德',0),
('諸葛亮',1,'字孔明',0),
('孫權',1,'字仲謀',0),
('賈寶玉',1,'榮國府公子',0),
('林黛玉',0,'金陵十二釵之冠',0),
('薛寶釵',0,'薛姨媽之女',0),
('王熙鳳',0,'賈璉之妻',0),
('賈母',0,'寶玉祖母',0),
('宋江',1,'呼保義',0),
('盧俊義',1,'玉麒麟',0),
('吳用',1,'智多星',0),
('公孫勝',1,'入雲龍',0),
('孫悟空',1,'唐僧的大徒弟',0),
('唐僧',1,'玄奘',0),
('豬八戒',1,'悟能',0),
('沙僧',1,'沙悟淨',0);
配置mysql數據庫日誌
通過日誌文件可以查看對數據庫的操作記錄,mysql默認不產生日誌文件,需要進行配置:
-
手動開啓日誌
進入mysql命令行:mysql -u root -p
查詢日誌狀態:show variables like 'general_log%';
開啓日誌:set global general_log = 'on';
-
自動開啓日誌
打開mysql配置文件my.ini
,路徑是C:\ProgramData\MySQL\MySQL Server 8.0
將general-log
的值修改爲1 -
重啓mysql服務
-
下載、安裝
baretail.exe
工具 -
在
baretail.exe
中打開日誌文件,
文件位置:C:\ProgramData\MySQL\MySQL Server 8.0\Data
中 -
在linux中使用
tail -f 日誌文件
,監控日誌的變化
查詢函數
通過模型類.objects
屬性可以調用如下函數,實現對模型類對應的數據表的查詢。
函數名 | 功能 | 返回值 | 說明 |
---|---|---|---|
get | 返回表中滿足條件的一條數據,並且只能是一條數據 | 模型類對象 | 參數中寫查詢條件。 1) 查到多條數據拋異常 MultipleObjectsReturned 2) 查詢不到數據拋異常 DoesNotExist |
all | 返回表格中所有數據 | QuerySet類型 | 查詢集 |
filter | 返回滿足條件的數據 | QuerySet類型 | 參數寫查詢條件 |
exclude | 返回不滿足條件的數據 | QuerySet類型 | 參數寫查詢條件 |
order_by | 對查詢結果進行排序 | QuerySet類型 | 參數中寫根據哪些字段進行排序 |
說明:
all函數以‘查詢集’的形式返回所有數據表中的記錄,該操作不會立限執行
只有使用了查詢集中的數據時纔會執行查詢
實例演練
- get函數示例:查詢圖書id爲3的圖書信息
def index(request):
list = BookInfo.objects.get(id=3)
print(list.id, list.btitle, list.bpub_date, list.bread, list.bcomment)
return render(request, 'app/index.html')
- all函數示例:查詢圖書所有信息
def index(request):
list = BookInfo.objects.all()
for book in list:
print(book.id, book.btitle, book.bpub_date, book.bread, book.bcomment)
return render(request, 'app/index.html')
條件查詢
在Django中,通過調用過濾器filter()
、exclude()
、get()
等實現SQL中的where子句
語法格式:
屬性名稱__比較運算符 = 值
說明:
- 屬性名稱和比較運算符間使用
兩個下劃線
- 通過"屬性名_id"表示外鍵對應對象的id值。
條件運算符
修改views.py文件,在index視圖中編寫如下查詢代碼:
- 等值查詢
exact:表示判等
例:查詢編號爲1的圖書
list=BookInfo.objects.filter(id__exact=1)
可簡寫爲:
list=BookInfo.objects.filter(id=1)
def index(request):
list = BookInfo.objects.filter(id__exact=1)
for book in list:
print(book.btitle, book.bpub_date)
return render(request, 'app/index.html')
- 模糊查詢
contains:是否包含
說明:如果要包含%無需轉義,直接寫即可。
例:查詢書名包含'傳'的圖書
list = BookInfo.objects.filter(btitle__contains='傳')
startswith、endswith:以指定值開頭或結尾。
例:查詢書名以'夢'結尾的圖書
list = BookInfo.objects.filter(btitle__endswith='夢')
以上運算符都區分大小寫,在這些運算符前加上i表示不區分大小寫,如iexact、icontains、istartswith、iendswith.
- 空查詢
isnull:是否爲null。
例:查詢書名不爲空的圖書。
list = BookInfo.objects.filter(btitle__isnull=False)
- 範圍查詢
in:是否包含在範圍內。
例:查詢編號爲1或3或5的圖書
list = BookInfo.objects.filter(id__in=[1, 3, 5])
- 比較查詢
gt、gte、lt、lte:大於、大於等於、小於、小於等於。
注意:參數中不能使用等號之外的比較符號
BookInfo.objects.filter(id > 3)
這種寫法是錯誤的
例:查詢編號大於3的圖書
list = BookInfo.objects.filter(id__gt=3)
不等於的運算符,使用exclude()過濾器。
例:查詢編號不等於3的圖書
list = BookInfo.objects.exclude(id=3)
- 日期查詢
year、month、day、week_day、hour、minute、second:對日期時間類型的屬性進行運算。
例:查詢1980年發表的圖書。
list = BookInfo.objects.filter(bpub_date__year=1980)
例:查詢1980年1月1日後發表的圖書。
list = BookInfo.objects.filter(bpub_date__gt=date(1990, 1, 1))
- F對象
之前的查詢都是屬性與常量值比較,如果是兩個屬性比較,可以通過F對象進行
F對象被定義在django.db.models
中
語法格式:F(屬性名)
例:查詢閱讀量大於等於評論量的圖書。
from django.db.models import F
list = BookInfo.objects.filter(bread__gte=F('bcomment'))
可以在F對象上使用算數運算。
例:查詢閱讀量大於2倍評論量的圖書
list = BookInfo.objects.filter(bread__gt=F('bcomment') * 2)
- Q對象
多個過濾器逐個調用表示邏輯與關係,相當於where子句的AND關鍵字。
例:查詢閱讀量大於20,並且編號小於3的圖書。
list=BookInfo.objects.filter(bread__gt=20,id__lt=3)
或
list=BookInfo.objects.filter(bread__gt=20).filter(id__lt=3)
如果需要實現邏輯或(OR)查詢,需要使用Q()對象結合 | 運算符,
Q對象被義在django.db.models中。
語法格式:Q( 屬性名__運算符 = 值 )
例:查詢閱讀量大於20的圖書,改寫爲Q對象如下。
from django.db.models import Q
list = BookInfo.objects.filter(Q(bread__gt=20))
Q對象可以使用&、|連接,&表示邏輯與,|表示邏輯或。
例:查詢閱讀量大於20,或編號小於3的圖書,只能使用Q對象實現
list = BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3))
Q對象前可以使用~操作符,表示非not。
例:查詢編號不等於3的圖書。
list = BookInfo.objects.filter(~Q(pk=3))
聚合函數
使用aggregate()
函數調用聚合函數。
聚合函數包括:Avg
,Count
,Max
,Min
,Sum
,被定義在django.db.models
中
aggregate()
返回一個字典類型,格式爲{' 屬性名小寫__聚合函數名小寫 ' :值}
,例如:{'bread__sum':3}
例:查詢圖書的總閱讀量。
from django.db.models import Sum
def index(request):
s = BookInfo.objects.aggregate(Sum('bread'))
print(s['bread__sum'])
return render(request, 'app/index.html')
count函數返回一個數字,一般不使用aggregate()過濾器。
例:查詢圖書總數。
c = BookInfo.objects.count()
查詢集(QuerySet)
查詢集表示從數據庫中獲取的對象集合,在管理器上調用某些過濾器方法會返回查詢集,查詢集可以含有零個、一個或多個過濾器。過濾器基於所給的參數限制查詢的結果,從Sql的角度,查詢集和select語句等價,過濾器像where和limit子句。
返回查詢集的過濾器如下:
- all():返回所有數據。
- filter():返回滿足條件的數據。
- exclude():返回滿足條件之外的數據,相當於sql語句中where部分的not關鍵字。
- order_by():對結果進行排序。
返回單個值的過濾器如下:
- get():返回單個滿足條件的對象
- 如果未找到會引發"模型類.DoesNotExist"異常。
- 如果多條被返回,會引發"模型類.MultipleObjectsReturned"異常。
- count():返回當前查詢結果的總條數。
- aggregate():聚合,返回一個字典。
判斷某一個查詢集中是否有數據:
- exists():判斷查詢集中是否有數據,如果有則返回True,沒有則返回False。
兩大特性
- 惰性執行:創建查詢集不會訪問數據庫,直到調用數據時,纔會訪問數據庫,調用數據的情況包括迭代、序列化、與if合用。
- 緩存:使用同一個查詢集,第一次使用時會發生數據庫的查詢,然後把結果緩存下來,再次使用這個查詢集時會使用緩存的數據。
示例:查詢所有,編輯booktest/views.py的index視圖,運行查看。
list=BookInfo.objects.all()
查詢集的緩存
每個查詢集都包含一個緩存來最小化對數據庫的訪問。
在新建的查詢集中,緩存爲空,首次對查詢集求值時,會發生數據庫查詢,django會將查詢的結果存在查詢集的緩存中,並返回請求的結果,接下來對查詢集求值將重用緩存中的結果。
- 如下是兩個查詢集,無法重用緩存,每次查詢都會與數據庫進行一次交互,產生2條SQL語句,增加了數據庫的負載。
from booktest.models import BookInfo
[book.id for book in BookInfo.objects.all()]
[book.id for book in BookInfo.objects.all()]
- 經過存儲後,可以重用查詢集,只產生1條SQL語句,第二次使用緩存中的數據。
list=BookInfo.objects.all()
[book.id for book in list]
[book.id for book in list]
限制查詢集 (LIMIT子句)
可以對查詢集進行取下標或切片操作,等同於sql中的limit和offset子句,對查詢集進行切片後返回一個新的查詢集,不會立即執行查詢
注意:不支持負數索引。
獲取一個對象,直接使用[0],等同於[0:1].get(),[0]
如果沒有數據,引發IndexError
異常,[0:1].get()
如果沒有數據,引發DoesNotExist
異常。
示例:獲取第1、2項,運行查看。
list=BookInfo.objects.all()[0:2]