溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解Django ORM操作

發(fā)布時間:2021-10-20 16:38:51 來源:億速云 閱讀:117 作者:iii 欄目:web開發(fā)

這篇文章主要講解了“如何理解Django ORM操作”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何理解Django ORM操作”吧!

查詢

聚合操作

聚合操作,不要被名字嚇到了,通常用在篩選完一些數據之后,求一下平均值了,什么的。

例如:求所有書的總價格和平均價格

原生sql

SELECT     SUM(price) AS "所有書總價格",     avg(price) AS "所有書平均價格" FROM web_book;

T SUM(price) AS "所有書總價格", avg(price) AS "所有書平均價格"FROMweb_book;

執(zhí)行結果

如何理解Django ORM操作

ORM

price = models.Book.objects.all().aggregate(Sum("price"),Avg("price"), ) print(price)

執(zhí)行結果

如何理解Django ORM操作

可以發(fā)現(xiàn)和上面是一樣的,但是會發(fā)現(xiàn)列名是默認是字段__聚合函數名。

原生sql是可以指定顯示的列名的,同樣,ORM也可以。

代碼

# 需要導入的包 from django.db.models import Avg,Sum  price = models.Book.objects.all().aggregate(所有書總價格=Sum("price"), 所有書平均價格=Avg("price"), ) print(price)

執(zhí)行結果

如何理解Django ORM操作

:price的類型直接就是dict,所以,在這是不能查看原生sql的。

但是上述ORM對應的原生SQL確實如上,所以那樣理解就行了。

分組操作

分組操作,就是將某一列,相同的值進行壓縮,然后就可以得出壓縮值的數量。

如果壓縮的是外鍵,還可以取出外鍵的詳細信息。

示例:查詢出每個出版社出版的數量。

通過研究表結構發(fā)現(xiàn),每出版的書,都在book表中記錄,并且每本書會外鍵一個出版社id。

如何理解Django ORM操作

如果我們能對出版社id進行壓縮,然后再求出壓縮出版社id里面對應的數量。

嘖嘖,這不就出來了嗎?

代碼

from django.db.models import Count  ret = models.Book.objects.values("publish_id").annotate(publish_count=Count("publish_id")) print(ret)

執(zhí)行結果

如何理解Django ORM操作

原生sql

SELECT     `web_book`.`publish_id`,     COUNT(`web_book`.`publish_id`) AS `publish_count` FROM     `web_book` GROUP BY     `web_book`.`publish_id`;

ORM分組和原生SQL對應圖

這一塊,我記得當初我迷茫了一段時間,主要是不知道如何和原生SQL對應上,根據多次測試經驗,對應圖如下。

如何理解Django ORM操作

分組獲取外鍵字段信息

上述確實可以通過分組實現(xiàn)了功能。

但是上述只能獲取出版社id,并不能獲取出版社名啥的,但是如何獲取壓縮外鍵字段詳細信息呢?

代碼

ret = models.Book.objects.values("publish_id").annotate(publish_count=Count("publish_id")).values("publish__title","publish__phone","publish_count") print(ret)

執(zhí)行結果

如何理解Django ORM操作

:分組(annotate)后面跟的values。

里面只能寫外鍵字段的列和annotate里面的列,不能寫其他。

如果分組分的不是外鍵字段,那就不能再跟values!

分組再篩選

分組再篩選本質就是原生sql的group by .. having,將壓縮完的數據在進行條件判斷。

但是對壓縮的數據進行判斷只能通過having。

示例:查詢出版社出版的書大于2本的數據。

代碼

ret = models.Book.objects.values("publish_id") \     .annotate(publish_count=Count("publish_id")) \     .filter(publish_count__gt=2) print(ret)

執(zhí)行結果

如何理解Django ORM操作

F查詢

有時候,我們可能有這樣的需求,就是兩個列之間進行比較。

比如經典問題,一個商品,找到收藏數大于銷量的商品等之類的兩列進行比較的需求。

示例:查詢book表,評論數小于收藏數的數據。

代碼

from django.db.models import F  book = models.Book.objects.filter(comment_num__lt=F("collect_num")) print(book)

實際結果

如何理解Django ORM操作

執(zhí)行結果

如何理解Django ORM操作

F對象還支持加減乘除后的比較

示例:評論數小于兩倍收藏數的數據。

代碼

可是*,也可以是-,+,÷

from django.db.models import F  book = models.Book.objects.filter(comment_num__lt=F("collect_num")*2) print(book)

執(zhí)行結果

如何理解Django ORM操作

F對象還適用于更新

代碼

models.Book.objects.all().update(price=F("price")+30)

Q查詢

通常情況下,我們使用的filter(條件1,條件2,...),執(zhí)行的都是and查詢。

但是通常一些時候,我們需要執(zhí)行or查詢。

比如book表,查詢title=<<大明帝國>> or title=<<安史之亂>>的。

這時候,如果使用Django ORM,就只能使用Q查詢構建條件。

代碼

from django.db.models import Q  books = models.Book.objects.filter(Q(title="<<大明帝國>>") | Q(title="<<安史之亂>>")) print(books)

執(zhí)行結果

如何理解Django ORM操作

:|是or的意思,&是and的意思。

所以,如果將上述的|換成&,filter(條件1,條件2,...)一個意思,還是and。

Q查詢之~

~相當于not。

示例:查詢title = "<<大明帝國>>" or title != "<<安史之亂>>"。

代碼

from django.db.models import Q  books = models.Book.objects.filter(Q(title="<<大明帝國>>") | ~Q(title="<<安史之亂>>")) print(books)

執(zhí)行結果

如何理解Django ORM操作

Q查詢和and混合查詢

Q查詢和and查詢同時出現(xiàn),Q查詢必須在其他查詢之前。

示例:查詢title = "<<大明帝國>>" or title != "<<安史之亂>>"  并且publish_id=1的。

代碼

from django.db.models import Q  books = models.Book.objects.filter(Q(title="<<大明帝國>>") | ~Q(title="<<安史之亂>>"),publish_id=1) print(books)

執(zhí)行結果

如何理解Django ORM操作

動態(tài)構造Q查詢

一些時候,我們可能并不太確定有什么條件。

可能是動態(tài)傳的,傳過來多少,就拼接多少。

Q查詢,就能做到這個,在做動態(tài)Q查詢時,動態(tài)Q不僅支持or,還支持and。

示例:查詢publish_id=1或者title模糊=大明 的書。

代碼

q = Q() # 查詢方式,or還是and q.connector = "or"  # or,and # publish_id=1 q.children.append(("publish_id", "1")) # title__contains="大明" q.children.append(("title__contains", "大明"))  books = models.Book.objects.filter(q) print(books)

執(zhí)行結果

如何理解Django ORM操作

上面說了那么多,終于算是大概說完了,來簡單看一下怎么添加一條數據吧。

示例:添加一本書

代碼

方式一,通過objects.create。

這種方式用的最多。

models.Book.objects.create(     title="<<人類簡史2>>",     price=66.66,     PublishDate="2020-01-02",     comment_num=23,     collect_num=12,     # 外鍵字段 django models對應的mysql 為 字段_id     publish_id=1,     # publish字段需要是一個 Publish 對象     # publish=models.Publish.objects.filter(id=1) )

方式二,通過model對象.save()。

book_obj = models.Book(     title="<<人類簡史2>>",     price=66.66,     PublishDate="2020-01-02",     comment_num=23,     collect_num=12,     # 外鍵字段 django models對應的mysql 為 字段_id     publish_id=1, ) book_obj.save()

方式三,通過字典方式。

可能有的時候,我們正好將傳過來的參數構造成了一個字典,那就太好了,不需要再一個個取。

c_dict = {     "title":"<<tcp編程從入門到精通2>>",     "price":88.1,     "PublishDate":"2020-01-03",     "comment_num":13,     "collect_num":78,     "publish_id":1, } models.Book.objects.create(**c_dict)

更新

:update只能跟在在filter之后。

示例:將title="<<大明帝國>>"的數據修改為title="<<大明帝國666>>"。

代碼

models.Book.objects.filter(title="<<大明帝國>>").update(title="<<大明帝國666>>")

filter可能篩選到的是多個值,一定要注意

刪除

delete只能跟在filter之后。

示例:刪除title=<<大明帝國666>>的數據。

models.Book.objects.filter(title="<<大明帝國666>>").delete()

感謝各位的閱讀,以上就是“如何理解Django ORM操作”的內容了,經過本文的學習后,相信大家對如何理解Django ORM操作這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI