1. 程式人生 > >django的數據庫操作-16

django的數據庫操作-16

屬性 返回 閱讀 西遊記 gate port 一個 運行環境 python

目錄

    • 1.save
    • 2.create
    • 1.基本查詢
    • 2.過濾查詢
    • 3. F對象
    • 4. Q對象
    • 5. 聚合函數
    • 6. 排序
    • 7. 關聯查詢
    • 8. 關聯+過濾查詢
    • 1. save
    • 2. update

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

django的數據庫操作-16