ORM(三)QuerySet查詢字段操作


這里的環境還是用上次的環境:

Django項目:orm_practice

app/models.py中有如下幾個類:

models.py

publishing表內容如下:

pid    name
1    機械工業出版社
2    電子工業出版社
3    人民出版社
4    圖靈出版社
5    科學出版社
app_publishing

app_books表內容如下:

bid   name            price    pid_id
1     雪山飛狐         40       3
2     三國演義         50       1
3     天龍八部         60       3
4     紅樓夢           50       2
5     C語言程序設計     80       4
6     水滸傳           50       5
                

app_author表內容如下:

aid   name          
1     金庸            
2     羅貫中        
3     曹雪芹        
4     施耐庵        
5     丹尼斯里奇      
    

app_author_books表內容如下:

id     author_id       books_id
1      1                1
2      1                3
3      2                2
4      3                4
5      4                6
6      5                5

有了以上的表后,下面進行字段操作,在進行操作之前我們先創建一個腳本,用於運行ORM的語句。

腳本內容:

import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")
    import django
    django.setup()
orm運行腳本

這里新建一個script的目錄,在該目錄下新建一個script.py的Python文件,在里面添加上面的腳本頭,最后看起來像下面這個樣子:

1、表的查詢QuerySet

all():以列表的形式返回表中所有字段信息。

語法:models.表名.objects.all()

import os
if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")
    import django
    django.setup()

from app import models
obj = models.Publishing.objects.all()   # 獲取Publishing表中所有字段信息
print(obj,type(obj))    # 打印publishing表總所有字段

# 打印內容如下
<QuerySet [<Publishing: Publishing object>, <Publishing: Publishing object>, <Publishing: Publishing object>,
<Publishing: Publishing object>, <Publishing: Publishing object>]> <class 'django.db.models.query.QuerySet'>

 可能結果我們返回的字段類型class 'django.db.models.query.QuerySet' ,並且打印的內容也不是很友好,這是因為我們沒有處理字段如何顯示(也就是沒有處理表中的屬性如何顯示),我們在創建publishing類時繼承了models.Model類,class Publishing(models.Model):由於我們沒有處理字段顯示,所以就到父類中去尋找顯示字段的方法,而父類models.Model為我們定義了__str__方法用於顯示字段,所以我們看到的字段信息是繼承了父類的顯示方法。

 

 既然我們知道了字段顯示方法,那么我們就可以自己定義字段顯示方法__str__()。

再次打印publishing表的字段信息,為便於查看結果,這回使用for循環的方式打印:

obj_all = models.Publishing.objects.all()
for obj in obj_all:
    print(obj.pid,obj.name)
print(type(obj_all))

# 打印內容如下
1 機械工業出版社
2 電子工業出版社
3 人民出版社
4 圖靈出版社
5 科學出版社
<class 'django.db.models.query.QuerySet'>

fileter(*args, **kwargs):如果不寫參數,默認返回所有表字段信息。關鍵字參數kwargs用於設置查詢條件,返回QuerySet類型列表。

語法:models.表名.objects.filter(關鍵字參數)

obj_list = models.Publishing.objects.filter()  # 沒有設置查找條件,默認打印表中所有內容
for obj in obj_list:
    print(obj.pid,obj.name)

# 打印內容如下
1 機械工業出版社
2 電子工業出版社
3 人民出版社
4 圖靈出版社
5 科學出版社

查找pid = 3的出版社。

obj_list = models.Publishing.objects.filter(pid=3)
print(obj_list[0].pid,obj_list[0].name,type(obj_list))  # filter返回的是一個QuerySet類型的列表,這里需要注意下。

# 打印內容如下
3 人民出版社 <class 'django.db.models.query.QuerySet'>

這里需要注意的是filter(條件)返回的是QuerySet類型的列表的所有符合條件的字段信息,還有一個地方就是Django為我們將主鍵位置封裝了一個類似別名pk,這樣我們在使用主鍵作為條件查找時,如果不記得主鍵名稱可以使用pk來代替主鍵。如下pk=3將得到和上面一樣的結果:

# obj_list = models.Publishing.objects.filter(pid=3)
obj_list = models.Publishing.objects.filter(pk=3)  # 這里使用pk作為主鍵進行查找
print(obj_list[0].pid,obj_list[0].name,type(obj_list))

# 打印內容如下
3 人民出版社 <class 'django.db.models.query.QuerySet'>

exclude(*args, **kwargs):如果不寫參數,會顯示所有字段信息。指定排除條件kwargs,返回與條件不匹配的QuerySet類型列表。

語法:models.表名.objects.exclude(關鍵字參數)

obj_list = models.Publishing.objects.exclude(pk=2)  # 這里排除主鍵是2的對象
for obj in obj_list:
    print(obj.pid,obj.name)

# 打印內容如下
1 機械工業出版社
3 人民出版社
4 圖靈出版社
5 科學出版社

order_by(*field_names):根據字段名就行排序。

obj_all = models.Publishing.objects.all().order_by("pk")  # 升序
for obj in obj_all:
    print(obj.pid,obj.name)

# 打印內容如下
1 機械工業出版社
2 電子工業出版社
3 人民出版社
4 圖靈出版社
5 科學出版社

下面是降序:

obj_all = models.Publishing.objects.all().order_by("-pk")  # 在字段前加一個負號代表降序
for obj in obj_all:
    print(obj.pid,obj.name)

# 打印內容如下
5 科學出版社
4 圖靈出版社
3 人民出版社
2 電子工業出版社
1 機械工業出版社

reverse():將列表對象顛倒,必須要和order_by配合使用,否則不生效

obj_all = models.Publishing.objects.all().order_by("pk")
for obj in obj_all[:3]:    # 打印列表的前三個對象
    print(obj.pid,obj.name)
print("-"*20)
for obj in obj_all.reverse()[:3]: # 顛倒后打印列表的前三個對象
    print(obj.pid,obj.name)

# 打印內容如下
1 機械工業出版社
2 電子工業出版社
3 人民出版社
--------------------
5 科學出版社
4 圖靈出版社
3 人民出版社

values(*fields, **expressions):將QuerySet類型列表中的對象轉換成字典。可指定*fields只查看要顯示的字段。

obj_all = models.Publishing.objects.all().values()  
print(obj_all,type(obj_all))

# 打印內容如下
<QuerySet [{'pid': 1, 'name': '機械工業出版社'}, 
{'pid': 2, 'name': '電子工業出版社'}, {'pid': 3, 'name': '人民出版社'}, {'pid': 4, 'name': '圖靈出版社'}, 
{'pid': 5, 'name': '科學出版社'}]> <class 'django.db.models.query.QuerySet'>

指定*fields只查看書籍的bid、name、price字段:

obj_all = models.Books.objects.all().values("bid","name","price")  # 只查看書籍的bid、name、price字段 for obj in obj_all:
    print(list(obj.items()))  # 使用items()查看字典中的值

# 打印內容如下
[('bid', 1), ('name', '雪山飛狐'), ('price', 40)]
[('bid', 2), ('name', '三國演義'), ('price', 50)]
[('bid', 3), ('name', '天龍八部'), ('price', 60)]
[('bid', 4), ('name', '紅樓夢'), ('price', 50)]
[('bid', 5), ('name', 'C語言程序設計'), ('price', 80)]
[('bid', 6), ('name', '水滸傳'), ('price', 50)]

distinct(*field_names):去除重復行,需要注意的是參數field_names在PostgreSQL中可以用,在mysql不能使用該值。

obj_all = models.Books.objects.all().values("price")
for obj in obj_all:  # 打印所有價格
    print(list(obj.items()))  
print("-"*20)
for obj in obj_all.distinct():  # 去掉重復價格
    print(list(obj.items())) 

# 打印內容如下
[('price', 40)]
[('price', 50)]
[('price', 60)]
[('price', 50)]
[('price', 80)]
[('price', 50)]
--------------------
[('price', 40)]
[('price', 50)]
[('price', 60)]
[('price', 80)]

values_list(*fields, **kwargs):fields用於指定字段顯示,以元組的形式返回結果,kwargs有一個參數flat用於將數據轉換成原數據類型,但只能轉換一個值。

指定"bid","name","price"字段打印內容:

obj_all = models.Books.objects.all().values_list("bid","name","price")
for obj in obj_all:  # 打印所有價格
    print(obj)

# 打印內容如下
(1, '雪山飛狐', 40)
(2, '三國演義', 50)
(3, '天龍八部', 60)
(4, '紅樓夢', 50)
(5, 'C語言程序設計', 80)
(6, '水滸傳', 50)

指定"name"字段使用flat=True打印"name"的原數據類型。

obj_all = models.Books.objects.all().values_list("name",flat=True)
for obj in obj_all:  # 打印所有價格
    print(obj)

# 打印內容如下
雪山飛狐
三國演義
天龍八部
紅樓夢
C語言程序設計
水滸傳

dates(field_name, kind, order='ASC')

field_name:字段名

kind:取值范圍是"year", "month", "day"

        year:返回該字段的所有不同年份值的列表。

   month:返回該字段的所有不同年/月值的列表。

   day:返回該字段的所有不同年/月/日值的列表。

order:"ASC","DESC"

我們在書籍字段中插入一列日期記錄,插入后的表如下:

bid    name               pid_id    price     date
1      雪山飛狐             3        40        2019-04-10
2      三國演義             1        50        2019-04-09
3      天龍八部             3        60        2018-04-10
4      紅樓夢               2        50        2017-04-10
5      C語言程序設計         4        80        2019-02-10
6      水滸傳               5        50        2019-04-10

下面分別對去除重復的年,月,日:

obj_year = models.Books.objects.dates("date","year")    # 去掉相同年份的
obj_month = models.Books.objects.dates("date","month")  # 去掉同年同月
obj_day = models.Books.objects.dates("date","day")      # 去掉同年同月同日生
for obj in obj_year:  # 去掉相同年份的
    print(obj)
print("-"*20)
for obj in obj_month:  # 去掉同年同月
    print(obj)
print("-"*20)
for obj in obj_day:  # 去掉同年同月同日生
    print(obj)

# 打印內容如下
2017-01-01
2018-01-01
2019-01-01
--------------------
2017-04-01
2018-04-01
2019-02-01
2019-04-01
--------------------
2017-04-10
2018-04-10
2019-02-10
2019-04-09
2019-04-10

datetimes(field_name, kind, order='ASC', tzinfo=None):與dates()類似,這里不演示了。

ield_name:字段名

kind:取值范圍是"year", "month", "day"

        year:返回該字段的所有不同年份值的列表。

   month:返回該字段的所有不同年/月值的列表。

   day:返回該字段的所有不同年/月/日值的列表。

  "hour":返回該字段的所有不同年/月/日 小時值的列表。

  "minute":返回該字段的所有不同年/月/日 小時:分鍾值的列表。

  "second"::返回該字段的所有不同年/月/日 小時:分鍾:秒值的列表。

order:"ASC","DESC"

 

none():將創建一個永遠不會返回任何對象的查詢集,並且在訪問結果時不會執行任何查詢。

obj_all = models.Books.objects.all().none()
print(obj_all)

# 打印內容如下
<QuerySet []>

exists():如果獲取到結果返回True,否則返回False。

obj_list = models.Books.objects.filter(pk=1).exists()  # 表中存在的主鍵
obj_list2 = models.Books.objects.filter(pk=10).exists()  # 表中不存在的主鍵
print(obj_list)
print(obj_list2)

# 打印內容如下
True
False

first()、last():獲取第一個和獲取最后一個對象。

obj_list = models.Books.objects.all()

print(obj_list.first())  # 獲取第一個對象
print(obj_list.last())  # 獲取最后一個對象

# 打印內容如下
雪山飛狐 - 40
水滸傳 - 50

上面只顯示書籍名字,和價格的原因是。我們在Books表中的顯示方式只指定了name和price

count():獲取對象個數。

obj_num = models.Books.objects.all().count()
print(obj_num)

# 打印內容如下
6

get(*args, **kwargs):必須給定查找條件,如果不指定查找條件會報錯,並且查找條件的匹配結果必須是只有一條記錄,如果返回多條記錄也會報錯,如果查找條件沒有匹配的結果也會報錯。所以在使用get時必須非常確根據條件肯定能獲取到結果,且結果只有一條記錄。否則會報錯。get是直接返回查找到的記錄(也就是類的對象)。

obj = models.Publishing.objects.get(pk=4)
print(obj.name,type(obj))

# 打印內容如下
圖靈出版社 <class 'app.models.Publishing'>

 

參考網址:https://docs.djangoproject.com/en/1.11/ref/models/querysets/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM