1. 欄位查詢 通過模型類.objects屬性可以調用如下函數,實現對模型類對應的數據表的查詢。 函數名 功能 返回值 說明 get 返回表中滿足條件的一條且只能有一條數據。 返回值是一個模型類對象。 參數中寫查詢條件。 1)如果查到多條數據,則拋異常MultipleObjectsReturned。 ...
1. 欄位查詢
通過模型類.objects屬性可以調用如下函數,實現對模型類對應的數據表的查詢。
函數名 |
功能 |
返回值 |
說明 |
get |
返回表中滿足條件的一條且只能有一條數據。 |
返回值是一個模型類對象。 |
參數中寫查詢條件。 1)如果查到多條數據,則拋異常MultipleObjectsReturned。 2)查詢不到數據,則拋異常:DoesNotExist。 |
all |
返回模型類對應表格中的所有數據。 |
返回值是QuerySet類型 |
查詢集 |
filter |
返回滿足條件的數據。 |
返回值是QuerySet類型 |
參數寫查詢條件。 |
exclude |
返回不滿足條件的數據。 |
返回值是QuerySet類型 |
參數寫查詢條件。 |
order_by |
對查詢結果進行排序。 |
返回值是QuerySet類型 |
參數中寫根據哪些欄位進行排序。 |
get、all前面已經使用過了,下麵主要講解filter、exclude和order_by的使用。
準備數據:
index.html:
<html> <head> <title>圖書列表</title> </head> <body> <h1>{{title}}</h1> {%for i in list%} {{i.id}}<br> {{i.btitle}}<br> {{i.bpub_date}}<br> {{i.bread}}<br> {{i.bcomment}}<br> {%endfor%} </body> </html>
我們後面的查詢只需要在views.py中修改代碼就行了。
1.1 查看mysql資料庫日誌
為了方便查看查詢結果,我們先配置下,讓系統生成mysql日誌文件。
我使用的是mysql5.7版本,其他版本可以參考這個,但是建議是自己去百度。
查看mysql資料庫日誌可以查看對資料庫的操作記錄需要做如下配置:
首先查看是否開啟了binlog:show binary logs;
發現沒有開啟logs,那麼我們就可以開始配置了。
我們要去C:\ProgramData\MySQL\MySQL Server 5.7路徑下找到my.ini文件。
然後編輯這個文件,我們可以使用搜索功能。
修改成這樣:
# Binary Logging. log-bin=mysql-bin binlog-format=Row
如果不能修改,就使用管理員許可權打開。
然後重啟mysql服務。
驗證binlog是否開啟:show variables like 'log_bin'; 和 show binary logs;
binlog文件的位置:如果在修改my.ini的binlog時給的是全路徑,那麼生成的日誌文件就在指定的目錄下;如果只給一個名字,那麼生成的binlog日誌的位置為:
如果給的全路徑配置為:
log-bin=指定路徑\mysql-bin
binlog-format=Row
那麼就會在指定路徑下生成文件。
1.2 條件運算符
1.2.1 查詢
exact:表示判斷等於,和 = 差不多。
例:查詢編號為1的圖書。
list=BookInfo.objects.filter(id__exact=1)
可簡寫為:
list=BookInfo.objects.filter(id=1)
1.2.2 模糊查詢
contains:是否包含。
如果要包含%無需轉義,直接寫即可。
list = BookInfo.objects.filter(btitle__contains='鬥')
startswith、endswith:以指定值開頭或結尾。
例:查詢書名以'天'結尾的圖書。
list = BookInfo.objects.filter(btitle__endswith='天')
以上運算符都區分大小寫,在這些運算符前加上i表示不區分大小寫,如iexact、icontains、istartswith、iendswith。
1.2.3 空查詢
isnull:是否為null。
例:查詢書名不為空的圖書。
list = BookInfo.objects.filter(btitle__isnull=False)
1.2.4 範圍查詢
in:是否包含在範圍內。
例:查詢編號為1或3或5的圖書。
list = BookInfo.objects.filter(id__in=[1, 3, 5])
1.2.5 比較查詢
gt、gte、lt、lte:大於、大於等於、小於、小於等於。
例:查詢編號大於3的圖書。
list = BookInfo.objects.filter(id__gt=3)
不等於的運算符,使用exclude()過濾器。
例:查詢編號不等於3的圖書
list = BookInfo.objects.exclude(id=3)
1.2.6 日期查詢
year、month、day、week_day、hour、minute、second:對日期時間類型的屬性進行運算。
例:查詢2009年發表的圖書。
list = BookInfo.objects.filter(bpub_date__year=2009)
例:查詢2008年12月14日後發表的圖書。
from datetime import date ... list = BookInfo.objects.filter(bpub_date__gt=date(2008, 12, 14))
1.3 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)
1.4 Q對象
多個過濾器逐個調用表示邏輯與關係,同sql語句中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))
1.5 聚合函數
使用aggregate()過濾器調用聚合函數。聚合函數包括:Avg,Count,Max,Min,Sum,被定義在django.db.models中。
例:查詢圖書的總閱讀量。
from django.db.models import Sum ... sum = BookInfo.objects.aggregate(Sum('bread'))
修改界面
<html> <head> <title>圖書列表</title> </head> <body> <h1>{{title}}</h1> {{sum}}<br> </body> </html>
以及
from django.shortcuts import render from booktest.models import BookInfo from django.db.models import Sum def index(request): sum = BookInfo.objects.aggregate(Sum('bread')) context = {'title': '圖書列表', 'sum': sum} return render(request, 'booktest/index.html', context)
註意aggregate的返回值是一個字典類型,格式如下:
{'聚合類小寫__屬性名':值} 如:{'sum__bread':3}
使用count時一般不使用aggregate()過濾器。
例:查詢圖書總數。
count = BookInfo.objects.count()
參照上面修改代碼
註意count函數的返回值是一個數字。
2. 查詢集
查詢集表示從資料庫中獲取的對象集合,在管理器上調用某些過濾器方法會返回查詢集,查詢集可以含有零個、一個或多個過濾器。過濾器基於所給的參數限制查詢的結果,從Sql的角度,查詢集和select語句等價,過濾器像where和limit子句。
返回查詢集的過濾器如下:
- all():返回所有數據。
- filter():返回滿足條件的數據。
- exclude():返回滿足條件之外的數據,相當於sql語句中where部分的not關鍵字。
- order_by():對結果進行排序。
返回單個值的過濾器如下:
- get():返回單個滿足條件的對象
- 如果未找到會引發"模型類.DoesNotExist"異常。
- 如果多條被返回,會引發"模型類.MultipleObjectsReturned"異常。
- count():返回當前查詢結果的總條數。
- aggregate():聚合,返回一個字典。
判斷某一個查詢集中是否有數據:
- exists():判斷查詢集中是否有數據,如果有則返回True,沒有則返回False。
2.1 兩大特點
- 惰性執行:創建查詢集不會訪問資料庫,直到調用數據時,才會訪問資料庫,調用數據的情況包括迭代、序列化、與if合用。
- 緩存:使用同一個查詢集,第一次使用時會發生資料庫的查詢,然後把結果緩存下來,再次使用這個查詢集時會使用緩存的數據。
示例:查詢所有,編輯booktest/views.py的index視圖,運行查看。
list=BookInfo.objects.all()
2.2 查詢集的緩存
每個查詢集都包含一個緩存來最小化對資料庫的訪問。
在新建的查詢集中,緩存為空,首次對查詢集求值時,會發生資料庫查詢,django會將查詢的結果存在查詢集的緩存中,並返回請求的結果,接下來對查詢集求值將重用緩存中的結果。
演示:運行項目shell。
python manage.py shell
情況一:如下是兩個查詢集,無法重用緩存,每次查詢都會與資料庫進行一次交互,增加了資料庫的負載。
from booktest.models import BookInfo [book.id for book in BookInfo.objects.all()] [book.id for book in BookInfo.objects.all()]
情況二:經過存儲後,可以重用查詢集,第二次使用緩存中的數據。
list=BookInfo.objects.all() [book.id for book in list] [book.id for book in list]
2.3 限制查詢集
可以對查詢集進行取下標或切片操作,等同於sql中的limit和offset子句。
註意:不支持負數索引。
對查詢集進行切片後返回一個新的查詢集,不會立即執行查詢。
如果獲取一個對象,直接使用[0],等同於[0:1].get(),但是如果沒有數據,[0]引發IndexError異常,[0:1].get()如果沒有數據引發DoesNotExist異常。
示例:獲取第1、2項,運行查看。
list=BookInfo.objects.all()[0:2]