<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 4871字,需瀏覽 10分鐘

           ·

          2021-01-06 17:37

          擊上方“Python爬蟲與數(shù)據(jù)挖掘”,進行關注

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

          陸機雄才豈自保?李斯稅駕苦不早。

          前言

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

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

          查詢

          聚合操作

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

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

          原生sql

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

          執(zhí)行結果

          ORM

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

          執(zhí)行結果

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

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

          代碼

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

          執(zhí)行結果

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

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

          分組操作

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

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

          示例:查詢出每個出版社出版的數(shù)量

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

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

          嘖嘖,這不就出來了嗎?

          代碼

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

          執(zhí)行結果

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

          分組獲取外鍵字段信息

          上述確實可以通過分組實現(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í)行結果

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

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

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

          分組再篩選

          分組再篩選本質就是原生sqlgroup by .. having,將壓縮完的數(shù)據(jù)在進行條件判斷。

          但是對壓縮的數(shù)據(jù)進行判斷只能通過having

          示例:查詢出版社出版的書大于2本的數(shù)據(jù)。

          代碼

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

          執(zhí)行結果

          F查詢

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

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

          示例:查詢book表,評論數(shù)小于收藏數(shù)的數(shù)據(jù)。

          代碼

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

          實際結果

          執(zhí)行結果

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

          示例:評論數(shù)小于兩倍收藏數(shù)的數(shù)據(jù)。

          代碼

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

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

          執(zhí)行結果

          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í)行結果

          注:|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í)行結果

          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í)行結果

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

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

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

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

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

          代碼

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

          執(zhí)行結果


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

          示例:添加一本書

          代碼

          • 方式一,通過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()
          • 方式三,通過字典方式。

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

            c_dict = {    "title":"<>",    "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="<<大明帝國>>"的數(shù)據(jù)修改為title="<<大明帝國666>>"

          代碼

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

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

          刪除

          delete只能跟在filter之后。

          示例:刪除title=<<大明帝國666>>的數(shù)據(jù)。

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

          總結

          好了各位,到此為止,基本上,Django ORM操作基本完畢,至少80%的知識都覆蓋完畢。

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

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

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

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

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

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

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

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

          -------------------?End?-------------------

          往期精彩文章推薦:

          歡迎大家點贊,留言,轉發(fā),轉載,感謝大家的相伴與支持

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

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

          /今日留言主題/

          隨便說一兩句吧~~

          瀏覽 25
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  秋霞丝鲁片一区二区三区手机在绒免 | 麻豆AV无码精品一区二区色欲 | 淫色综合网| 91草莓视频 | 俺也来俺也去视频在线看 |