django的資料庫操作-16
目錄
Django的manage工具提供了shell命令,已經幫助我們配置好當前工程的執行環境(如連線好資料庫等),我們會在自帶終端中執行測試python語句。
manage.py
所在目錄執行命令
python manage.py shell
這打開了一個互動式命令列。
匯入模型類
from book.models import Book
from book.models import Role
匯入date包處理時間
from datetime import date
增
增加資料有兩種方式
1.save
建立模型類物件,再使用 save
儲存到資料庫中
新增書籍 “西遊記”
book = Book( b_title="西遊記", b_pub_date=date(1988,1,1), b_read=20, b_comment=10, is_delete=False) >>> book.save()
2.create
直接儲存到資料庫中
“西遊記”書籍新增角色 “孫悟空”
Role.objects.create(
r_name="孫悟空",
r_gender="1",
r_describe="猴哥",
r_book_id=book.id)
查
1.基本查詢
get 查詢單一結果,如果不存在會丟擲模型類.DoesNotExist異常,返回一個模型類物件。
all 查詢多個結果,返回一個查詢集。
count 查詢結果數量。
get
get 查詢單一結果,如果不存在會丟擲模型類.DoesNotExist異常。
查詢編號為5的書籍
>>> Book.objects.get(pk=5) <Book: Book object>
objects 是模型管理器,會在後邊有具體的講解。
pk代表primary key的縮寫,也就是任何model中都有的主鍵,當id也是主鍵的時候,我們可以認為pk和id是完全一樣的。但是當model的主鍵不是id的時候,兩者就有了區別。
輸出出來的 <Book: Book object>
無法看出是不是我們寫進去的資料,為了讓顯示更人性化,我們給資料庫模型新增一個 _str__
方法。
class Book(models.Model):
...
def __str__(self):
return self.b_title
class Role(models.Model):
...
def __str__(self):
return self.r_name
重啟shell,重新匯入模型類
>>> Book.objects.get(id=5)
<Book: 西遊記>
all
all 查詢多個結果。
查詢所有書
>>> Book.objects.all()
<QuerySet [<Book: 射鵰英雄傳>, <Book: 天龍八部>, <Book: 笑傲江湖>, <Book: 雪山飛狐>, <Book: 西遊記>]>
count
count 查詢結果數量。
獲得書籍數量
>>> Book.objects.count()
5
2.過濾查詢
過濾查詢實現sql語句中的 where
功能,包括:
filter 過濾出多個結果,返回一個查詢集
exclude 排除掉符合條件剩下的結果,返回一個查詢集
get 過濾單一結果
過濾查詢語法:
模型類名.objects.查詢方式(過濾條件)
過濾條件語法:
欄位名稱__條件運算子=值
條件運算子:
exact:相等。
contains:包含。
startswith:指定值開頭
endswith:指定值結尾
isnull:是否為null。
in:是否包含在範圍內。
gt: 大於 (greater then)
gte: 大於等於 (greater then equal)
lt: 小於 (less then)
lte: 小於等於 (less then equal)
year、month、day、week_day、hour、minute、second:對日期時間型別的屬性進行運算。
相等
exact:表示相等
查詢書名等於“西遊記”的書
>>> Book.objects.filter(b_title__exact="西遊記")
<QuerySet [<Book: 西遊記>]>
包含(模糊查詢)
contains:包含
書名包含“八”字的書
>>> Book.objects.filter(b_title__contains="八")
<QuerySet [<Book: 天龍八部>]>
開頭
書名“笑”開頭的數
>>> Book.objects.filter(b_title__startswith="笑")
<QuerySet [<Book: 笑傲江湖>]>
結尾
>>> Book.objects.filter(b_title__endswith="狐")
<QuerySet [<Book: 雪山飛狐>]>
空
isnull:是否為null
書名不為空
>>> Book.objects.filter(b_title__isnull=False)
<QuerySet [<Book: 射鵰英雄傳>, <Book: 天龍八部>, <Book: 笑傲江湖>, <Book: 雪山飛狐>, <Book: 西遊記>]>
包含(範圍)
in:是否包含在範圍內
編號 1,2,3的書
>>> Book.objects.filter(pk__in=[1, 2, 3])
<QuerySet [<Book: 射鵰英雄傳>, <Book: 天龍八部>, <Book: 笑傲江湖>]>
大於小於
gt: 大於 (greater then)
gte: 大於等於 (greater then equal)
lt: 小於 (less then)
lte: 小於等於 (less then equal)
編號大於3的書
>>> Book.objects.filter(pk__gt=3)
<QuerySet [<Book: 雪山飛狐>, <Book: 西遊記>]>
時間
year、month、day、week_day、hour、minute、second:對日期時間型別的屬性進行運算。
1995年的書
>>> Book.objects.filter(b_pub_date__year="1995")
<QuerySet [<Book: 笑傲江湖>]>
3. F物件
F()是代表模型欄位的值,可以用來修改欄位或者比較欄位。
匯入F物件
from django.db.models import F
F物件使用
F(欄位名)
閱讀量大於評論量
>>> Book.objects.filter(b_read__gt=F('b_comment'))
<QuerySet [<Book: 雪山飛狐>, <Book: 西遊記>]>
閱讀量大於評論量兩倍
>>> Book.objects.filter(b_read__gt=F('b_comment')*2)
<QuerySet [<Book: 雪山飛狐>]>
4. Q物件
隨著程式的複雜,查詢條件也會越來越複雜,類似前邊的查詢語句也會變得越來越長。
例如查詢閱讀量大於20且評論數大於30的書,需要這樣
>>> book = Book.objects.filter(b_read__gt=20)
>>> book.filter(b_comment__gt=30)
<QuerySet [<Book: 天龍八部>]>
或者這樣
>>> Book.objects.filter(b_read__gt=20).filter(b_comment__gt=30)
<QuerySet [<Book: 天龍八部>]>
但是這樣的語句是相當繁雜且不利於閱讀的。
Q()物件就是為了將這些條件組合起來。
Q物件可以使用 &
|
~
連線,&
表示邏輯與, |
表示邏輯或,~
表示非。
類似sql語句中where部分的 and
or
not
關鍵字。
匯入Q物件
from django.db.models import Q
使用Q物件實現查詢閱讀量大於20且評論數大於30的書
>>> Book.objects.filter(Q(b_read__gt=20)&Q(b_comment__gt=30))
<QuerySet [<Book: 天龍八部>]>
5. 聚合函式
使用aggregate()過濾器呼叫聚合函式。聚合函式包括:Avg 平均,Count 數量,Max 最大,Min 最小,Sum 求和。
需要從 django.db.models
中匯入,例如
from django.db.models import Sum
查詢最多閱讀數
>>> Book.objects.aggregate(Max('b_read'))
{'b_read__max': 58}
聚合函式查詢結果是一個字典型別
{'欄位名__聚合類小寫': 查詢結果}
6. 排序
使用 order_by
對查詢結果排序,返回一個查詢集。
按閱讀量排序
>>> Book.objects.all().order_by('b_read') # 升序排序
<QuerySet [<Book: 射鵰英雄傳>, <Book: 笑傲江湖>, <Book: 西遊記>, <Book: 天龍八部>, <Book: 雪山飛狐>]>
>>> Book.objects.all().order_by('-b_read') # 降序排序
<QuerySet [<Book: 雪山飛狐>, <Book: 天龍八部>, <Book: 笑傲江湖>, <Book: 西遊記>, <Book: 射鵰英雄傳>]>
7. 關聯查詢
一查多
語法
一方查詢物件.多方模型類名小寫__set
查詢“天龍八部”所有的角色
>>> book = Book.objects.get(b_title__exact="天龍八部")
>>> book.role_set.all()
<QuerySet [<Role: 喬峰>, <Role: 段譽>, <Role: 虛竹>, <Role: 王語嫣>]>
多查一
語法
多方查詢物件.多方有對應關係的欄位名
查詢“段譽”所在書名
>>> role = Role.objects.get(r_name__exact="段譽")
>>> role.r_book
<Book: 天龍八部>
8. 關聯+過濾查詢
根據多方條件查一方
語法格式
多方模型類名小寫__多方欄位名__條件運算子=值
查詢編號為1角色所在書籍
>>> Book.objects.filter(role__id__exact=1)
<QuerySet [<Book: 射鵰英雄傳>]>
查詢角色名字帶“黃”字的書籍
>>> Book.objects.filter(role__r_name__contains="黃")
<QuerySet [<Book: 射鵰英雄傳>, <Book: 射鵰英雄傳>]>
當查詢條件為等於的時候可以省略條件運算子
查詢編號為1角色所在書籍可以這樣寫
>>> Book.objects.get(role__id=1)
<Book: 射鵰英雄傳>
根據一方條件查多方
語法格式
多方有對應關係的欄位名__一方欄位名__查詢條件=值
查詢“雪山飛狐所有角色”
>>> Role.objects.filter(r_book__b_title__exact="雪山飛狐")
<QuerySet [<Role: 胡斐>, <Role: 苗若蘭>, <Role: 程靈素>, <Role: 袁紫衣>]>
查詢閱讀量大於30的書籍角色
>>> Role.objects.filter(r_book__b_read__gt=30)
<QuerySet [<Role: 喬峰>, <Role: 段譽>, <Role: 虛竹>, <Role: 王語嫣>, <Role: 胡斐>, <Role: 苗若蘭>, <Role: 程靈素>, <Role: 袁紫衣>]>
當查詢條件是等於的時候可以省略條件運算子
查詢“雪山飛狐所有角色”可以這樣寫
>>> Role.objects.filter(r_book__b_title="雪山飛狐")
<QuerySet [<Role: 胡斐>, <Role: 苗若蘭>, <Role: 程靈素>, <Role: 袁紫衣>]>
刪
刪除資料使用查詢結果物件的 delete
方法
語法格式
查詢結果物件.delete()
刪除閱讀量小於20的書
>>> Book.objects.filter(b_read__lt=20).delete()
(6, {'book.Role': 5, 'book.Book': 1})
一般刪除資料只使用邏輯刪除,即修改 is_delete
欄位為 True
改
修改資料有兩種方式
1. save
獲得 單個模型類 物件,修改資料後使用save儲存
>>> role = Role.objects.get(id__exact=18)
>>> role.r_name = "齊天大聖"
>>> role.save()
2. update
獲得 查詢集 物件,使用 update
方法修改資料,修改後會返回被影響資料條數
修改 id
大於15的角色名字為 “不知名人士”
>>> Role.objects.filter(id__gt=15).update(r_name="不知名人士")
4