一篇文章帶你了解Django ORM操作(高端篇)

2021-03-02 Python爬蟲與數據挖掘

回復「書籍」即可獲贈Python從入門到進階共10本電子書

前言

上次兩篇基本學完的Django ORM各種操作,怎麼查,各種查。感興趣的小夥伴可以戳這兩篇文章學習下,一篇文章帶你了解Django ORM操作(進階篇)、一篇文章帶你了解Django ORM操作(基礎篇)。

但是還是遺留了一些技能。,再來瞅瞅吧!

查詢聚合操作

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

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

原生sql

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

執行結果

ORM

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

執行結果

可以發現和上面是一樣的,但是會發現列名是默認是欄位__聚合函數名。

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

代碼

from django.db.models import Avg,Sum
price = models.Book.objects.all().aggregate(所有書總價格=Sum("price"), 所有書平均價格=Avg("price"), )print(price)

執行結果

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

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

分組操作

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

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

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

通過研究表結構發現,每出版的書,都在book表中記錄,並且每本書會外鍵一個出版社id

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

嘖嘖,這不就出來了嗎?

代碼

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

執行結果

原生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對應上,根據多次測試經驗,對應圖如下。

分組獲取外鍵欄位信息

上述確實可以通過分組實現了功能。

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

代碼

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

執行結果

注:分組(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)

執行結果

F查詢

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

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

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

代碼

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

實際結果

執行結果

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

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

代碼

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

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

執行結果

F對象還適用於更新

代碼

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

Q查詢

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

但是通常一些時候,我們需要執行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)

執行結果

注:|是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)

執行結果

Q查詢和and混合查詢

Q查詢and查詢同時出現,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)

執行結果

動態構造Q查詢

一些時候,我們可能並不太確定有什麼條件

可能是動態傳的,傳過來多少,就拼接多少

Q查詢,就能做到這個,在做動態Q查詢時,動態Q不僅支持or,還支持and

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

代碼

q = Q()q.connector = "or"  q.children.append(("publish_id", "1"))q.children.append(("title__contains", "大明"))
books = models.Book.objects.filter(q)print(books)

執行結果


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

示例:添加一本書

代碼

更新

: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操作基本完畢,至少80%的知識都覆蓋完畢。

本篇主要補充的是一些高端操作,例如聚合操作,分組操作,分組再篩選操作,F查詢和Q查詢

如何動態構造Q查詢。

相對來說,Django還是自由度比價高的,而且寫起來確實比較省心。

如果在操作過程中有任何問題,記得下面留言,我們看到會第一時間解決問題。

用微笑告訴別人,今天的我比昨天強,今後也一樣。

我是碼農星期八,如果覺得還不錯,記得動手點讚一下哈。感謝你的觀看。

如果你覺得文章還可以,記得點讚留言支持我們哈。感謝你的閱讀,有問題請記得在下方留言噢~

想學習更多關於Python的知識,可以參考學習網址:http://pdcfighting.com/,點擊閱讀原文,可以直達噢~

------------------- End -------------------

往期精彩文章推薦:

歡迎大家點讚,留言,轉發,轉載,感謝大家的相伴與支持

想加入Python學習群請在後臺回復【入群

萬水千山總是情,點個【在看】行不行

/今日留言主題/

隨便說一兩句吧~~

相關焦點

  • 一篇文章帶你了解Django Form組件(入門篇)
    普通版註冊代碼urls.pyfrom django.urls import path from web import views  urlpatterns = [     path('reg/', views.reg,), ]
  • django-admin和manage.py用法
    金句:所有的天賦,都來自於你對你喜歡的某種事物的模仿與學習,否則你就不會有這種天賦。記錄要點:django-admin和manage.py 能做同樣的事情 像我們常用的python manage.py runserver,用django-admin也可以操作:django-admim runserver 注意: django-admin需要提前提前配置好DJANGO_SETTINGS_MODULE環境變量
  • Python基礎教程——秒懂django操作資料庫
    Mariadb資料庫,簡單易用、性能高Python和django提供了完善的操作資料庫及事務的方法,首先明確一點,這很簡單,一點也不複雜,下面你會看到,10行代碼就搞定了。現在,先上結論:如果我們只是很簡單的操作一下資料庫,我們推薦使用mysqlclient這個第三方庫如果對資料庫的操作要做一些處理,資料庫又會變動,或者業務需求比較複雜,那就推薦使用django簡易操作代碼實在太簡單,如下所示:
  • Django第十八課
    (這裡我發現上一篇博客的問題:應該要展示前七天的閱讀數,因為當日的閱讀數是在不斷更新的,所以展示的話需要使用前七天的數據。在對日期進行控制的時候,range迭代器應該是range(7,0, -1))1.
  • 「原創」Django第六章、模型操作
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫模型的操作回顧上一章中我們建立了一個博客文章的模型,然後通過數據遷移建立我們對應中的資料庫表,這一章我們接著說模型的操作
  • 不吹不擂,你想要的Python面試都在這裡了【315+道題】
    有緣人如果看到這些題,不妨留言一下答案,來證明下你到底有多水,哈哈哈哈哈哈哈哈哈哈哈第一部分 Python基礎篇(
  • python測試開發django-76.ORM查詢之Q查詢
    >select * from yoyo_card where card_user = 'YOYO' or 'yoyo';filter() 查詢,查詢或關係MyDjango>python manage.py shell>>> from yoyo.models import Card>>> from django.db.models
  • 資源|Django全棧工程師學習
    18.另外,一篇關於Python和Django的博文中提到,在開發過程中,規劃好每一部分項目的所用時間,是非常必要的,這同時也是一個程式設計師需要養成的良好習慣。Django教學視頻:你是不是也在網絡上尋找一些與上述書籍或文章對應的教學視頻?
  • 一篇文章帶你了解Java中的抽象類和接口知識
    後臺回復「Java」即可獲贈Java學習資料    前面幾篇文章用
  • 一個完整的Django入門指南
    我的想法是在文章中穿插一些漫畫的方式來演示說明相應的概念和場景。我希望大家能夠享受這種閱讀!當年我在一所大學擔任代課教授時,我曾經在計算機科學專業給新來的學生講授網絡開發學科。那時我總是會用下面這個孔夫子的名言開始新的課程:(譯者註:不確定是孔子講的,但這句話早在中國古代就有所提到,出自荀子《儒效篇》「不聞不若聞之,聞之不若見之,見之不若知之,知之不若行之;學至於行之而止矣」)所以,請動起手來!
  • Django查詢資料庫操作詳解(一)
    原生資料庫操作方法所謂原生資料庫操作即使用 SQL 語句來進行資料庫的相關的查詢操作。那你可能會問,Django 已經有 ORM 了,為什麼還會提供原生語句的操作呢?Django 提供了遊標 cursor 對資料庫進行增刪改操作,在 Django 中執行非查詢語句必須使用遊標進行操作。
  • 8個能提高Django開發效率的Python包
    但是在此之前,你可以先看看我們之前寫的有關如何讓Django 管理更加安全的技巧,以及一篇關於5個最喜歡的開源Django包的文章。如果你在運營一個新聞網站,需要撰寫、編輯和發表文章,django-fsm可以幫助你定義這些狀態,並管理從一個狀態轉移到另一個狀態的規則和限制。Django-fsm提供了一個FSMField,用於定義模型實例狀態的model屬性。然後,您可以使用django-fsm的@transition裝飾器來定義將模型實例從一種狀態移動到另一種狀態的方法,並處理該轉換帶來的任何副作用。
  • 一篇文章帶你快速了解
    一篇文章帶你快速了解時間:2018-03-06 16:33   來源:360問答   責任編輯:沫朵 川北在線核心提示:原標題:育兒的蒙臺梭利教學法是什麼? 一篇文章帶你快速了解 如今,很多家長為了能讓兒童接受良好的教育費盡心思,甚至不惜重金。在這種情況下,出現了很多冠以蒙臺梭利教學法之名的教育網站、早教中心、私立幼兒園等。
  • 一篇文章帶你了解UR優傲機器人
    一篇文章帶你了解UR優傲機器人 2019年06月11日 13:10作者:黃頁編輯:黃頁 Universal Robots (優傲機器人)全系列機器人UR3、UR5、UR10具有:操作簡易,實用靈活、人機協作——人與機器人的安全合作、生產流程中的多樣化,多點化布置、低門檻和快速投資回報、高效節能、低噪音、模塊化設計等特點。優傲機器人產品應用包括:拾取放置, 注射成型, 電腦數控, 包裝堆垛, 質量檢驗, 組裝, 機器維保, 螺釘固定, 實驗室分析及測試, 膠合及焊接。
  • Django分頁完整示例
    大家好,在這篇文章中,我們將展示django的分頁完整的一個實例,當我們打算用Django中開發博客時,需要將帖子列表分別展示到多個頁面上,在這方面,
  • 最淺顯易懂的Django系列教程(1)-URL與視圖
    在視圖中,一般是完成邏輯相關的操作。比如這個請求是添加一篇博客,那麼可以通過request來接收到這些數據,然後存儲到資料庫中,最後再把執行的結果返回給瀏覽器。視圖函數的返回結果必須是HttpResponseBase對象或者子類的對象。
  • python程式設計師嘔心瀝血整理 Django 優秀資源大全
    django-fluent-dashboard, star:166 - Django 項目的增強型管理面板。django-grappelli, star:2087 - 可用於 Django 管理界面的一個絢麗皮膚。django-hijack, star:542 - 允許超級用戶以其他用戶微分登錄和操作。
  • 10道題教你使用python Django框架來實現web應用,值得收藏
    3、我現在系統需要一個功能,當一個任務到達某個狀態時,如果24小時沒有任何人操作,則自動切換到另一個狀態,對每個用戶是有不同的任務的,有點想百度外賣下單等待商家接單的那種,有什麼可以方便django整合一起的框架嗎?django-celery如何?簡單說一下我的考慮,供你參考。用戶下單後,用戶訂單信息寫入資料庫。商家接單後,修改資料庫中用戶訂單狀態。
  • 「原創」Django第五章、模型建立與遷移
    畢竟博客中最需要的就是文章嘛,好,閒話少敘,我們開始。通過這個類我們可以創建一個專門用來保存博客文章的資料庫表,代碼如下:from django.db import modelsfrom django.utils import timezone # 新增from django.contrib.auth.models import