日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Web框架之Django_05 模型层了解(单表查询、多表查询、聚合查询、分组查询)

發布時間:2024/9/30 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Web框架之Django_05 模型层了解(单表查询、多表查询、聚合查询、分组查询) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

閱讀目錄

  • 一、Django ORM 常用字段和參數:
  • 二、單表查詢
  • 三、多表查詢
  • 基于雙下劃線的多表查詢
  • 四、聚合查詢和分組查詢

摘要:

  • 單表查詢
  • 多表查詢
  • 聚合查詢
  • 分組查詢

一、Django ORM 常用字段和參數:
1:常用字段:
#AutoField
int自增列,必須填入參數primary_key = True,當model中如果沒有自增列,則會自動創建一個列名為id的列
#IntegerField
一個整數類型,范圍在–2147483648 to 2147483647。(一般不用它來存手機號(位數也不夠),直接用字符串存)
#CharField
字符類型,必須提供max_length參數,max_length表示字符長度
Tips:Django的CharField對應的MySQL數據庫中的varchar類型,沒有設置對應char類型的字段,但是Django允許我們自定義新的字段

-------------------------------------------------------------------- 注:如果你對python感興趣,我這有個學習Python基地,里面有很多學習資料,感興趣的+Q群:895817687 --------------------------------------------------------------------#應用上面自定義的char類型 class Class(models.Model):id=models.AutoField(primary_key=True)title=models.CharField(max_length=32)class_name=RealCharField(max_length=16)gender_choice=((1,'男'),(2,'女'),(3,'保密'))gender=models.SmallIntegerField(choices=gender_choice,default=3)

需要注意的是:自定義字段在實際項目應用中可能會經常用到,所以這里需要留意。
#DateField
日期字段,日期格式 YYYY-MM-MD,例如:2019-6-12,相當于Python中的datetime.date()實例。
#DateTimeField
日期格式字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相當于Python中的datetime.datetime()實例。

2:字段合集:

字段合集
ORM字段與MySQL字段對應關系

3:字段參數:

#null :用于表示某個字段可以為空
#unique :如果設置為unique = True 則該字段在此表中必須是唯一的
#db_index :如果db_index = True 則代表著為此字段設置索引
#default :為該字段設置默認值

4:DateField和DateTimeField:

#auto_now_add 配置auto_now_add = True,創建數據記錄的時候會把當前時間添加到數據庫,后續操作數據不自動更新
#auto_now 配置上auto_now = True,每次更新數據記錄的時候會更新該字段

5:關系字段:

#①ForeignKey 外鍵類型在ORM中用表示外鍵關聯關系,一般吧ForeignKey字段設置在‘一段多’中的多的一方,ForeignKey可以和其它表做關聯關系同時也可以和自身做關聯關系。
#字段參數:
##to 設置要關聯的表
##to_field 設置要關聯的表的字段
##on_delete 當刪除關聯表中的數據時,當前表與其關聯的行的行為 models.CASCADE (Django2.x版本必須要設置,1.x版本默認就設置了) 刪除關聯數據,與之關聯也刪除
##db_constraint 是否在數據庫中創建外鍵約束,默認為True

示例:

def func():return 10class MyModel(models.Model):user = models.ForeignKey(to="User",to_field="id"# 不寫默認關聯對方關聯表的primary_keyon_delete=models.SET(func))

#②OneToOneField
一對一字段
通常一對一字段用來擴展已有字段。(通俗的說就是一個人的所有信息不是放在一張表里面的,簡單的信息一張表,隱私的信息另一張表,之間通過一對一外鍵關聯)

#字段參數:
##to 設置要關聯的表
##to_field 設置要關聯的表的字段
##on_delete 當刪除關聯表中的數據時,當前與其關聯的行的行為(參考ForeignKey)
#③ManyToManyField
多對多字段
#字段參數:
##to 設置要關聯的表
##to_field 設置要關聯的表的字段
##on_delete 當刪除關聯表中的數據時,當前與其關聯的行的行為(參考ForeignKey)

二、單表查詢

  • 準備
    為了更方便的測試表查詢的結果,我們需要先配置一下參數,可以是我們直接在Django頁面中運行我們的測試表查詢代碼,快速顯示結果,所以需要做如下操作:
    項目根目錄創建一個test.py測試文件>>>>在項目的manage.py文件中復制一段代碼>>>>將復制的代碼粘貼到test.py文件中,然后再加入幾段代碼,這樣就可以在test文件中進行數據庫表數據操作了,當然,連接數據庫的過程不能少,表的創建也是。
manage.py文件復制的代碼: import os if __name__ == "__main__":os.environ.setdefault("DJANGO_SETTINGS_MODULE", "created_by_pycharm.settings")添加的代碼:(在main下面)import djangodjango.setup()from app01 import models # 注意這句話必須在這里,不能放最上面


這里需要建一張表,用于單表查詢:(models文件內)

from django.db import models# Create your models here. # 單表查詢示例表 class User(models.Model):name = models.CharField(max_length=32)age = models.IntegerField()register_time = models.DateField(auto_now_add=True) 項目settings里面將MySQL數據庫連入: DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'orm_test','HOST': '127.0.0.1','PORT': 3306,'USER': 'root','PASSWORD': '123',} }同時不要忘了在項目程序文件夾中init文件添加代碼: import pymysql pymysql.install_as_MySQLdb() 這樣才代表數據庫已經和Django項目對接完畢 當然新建完要生效,需要進行數據庫遷移(同步)操作python3 manage.py makemigrationspython3 manage.py migrate
  • 新增表數據
# 基于create創建models.User.objects.create(name='sgt', age=18)# 基于對象的綁定方法創建user_obj = models.User(name='王大錘', age=12)user_obj.save()
  • 修改表數據
# 基于QuerySetmodels.User.objects.filter(name='ttt').update(age=100)# 基于對象user_obj = models.User.objects.filter(name='sss').first()user_obj.age = 99user_obj.save()
  • 刪除表數據
# 基于QuerySetmodels.User.objects.filter(name='ggg').delete()# 基于對象user_obj = models.User.objects.filter(name='ttt').first()user_obj.delete()

總結一下單表操作的一些方法:
<1> all(): 查詢所有的結果,返回QuerySet對象們的列表

res = models.User.objects.all() print(res) <QuerySet [<User: User object>, <User: User object>, <User: User object>, <User: User object>]>

<2> filter(**kwargs): 通過括號中的條件查詢到匹配的對象,返回QuerySet對象們的列表

res = models.User.objects.filter(name='sgt') print(res) <QuerySet [<User: User object>, <User: User object>, <User: User object>]>這里提一下:filter篩選條件是可以有多個的,多個條件是與關系,必須全部滿足才會得到查詢結果

<3> get(**kwargs): 返回與所給篩選條件匹配的object對象,且返回結果只有一個,如果符合篩選條件的對象超過一個或者沒有都會拋出

res1 = models.User.objects.get(name='sgt') # app01.models.MultipleObjectsReturned: get() returned more than one User -- it returned 3! res2 = models.User.objects.get(name='孫悟空') # app01.models.DoesNotExist: User matching query does not exist. res3 = models.User.objects.get(name='王大錘') # User object

<4> exclude(**kwargs): 返回篩選條件不匹配的QuerySet對象們的列表(取反篩選)

res1 = models.User.objects.exclude(name='sgt') <QuerySet [<User: User object>, <User: User object>, <User: User object>]>

<5> order_by(*field): 對查詢結果通過某一字段進行排序(默認升序),返回QuerySet對象們的列表

res1 = models.User.objects.filter(name='sgt').order_by('age') # 排序默認是升序,如果這里的age前加上一個負號‘-’,怎會進行降序排序。 # res1 = models.User.objects.filter(name='sgt').order_by('-age') print(res1) # <QuerySet [<User: User object>, <User: User object>, <User: User object>]> # 為了讓結果更清晰,遍歷下得到排好序的QuerySet對象們列表,以其age顯示順序 users = [] for user_obj in res1:users.append(user_obj.age) print(users) # [18, 22, 32]

<6> reverse(): 對查詢的排序結果進行反向排列,記住,不是反向排序,而是反向排列,返回QuerySet對象們的列表

res1 = models.User.objects.filter(name='sgt').order_by('age').reverse() users = [] for user_obj in res1:users.append(user_obj.age) print(users) # 結果反過來排列了:[32, 22, 18]

<7> count(): QuerySet方法,返回查詢到的QuerySet對象的數量,該方法只能對返回的查詢結果為QuerySet對象使用,如果返回的對象

res1 = models.User.objects.filter(name='sgt').count() print(res1) # 3res2 = models.User.objects.filter(name='hahaha').count() print(res2) # 0res3 = models.User.objects.get(name='王大錘').count() # 拋出錯誤:AttributeError: 'User' object has no attribute 'count'

<8> first(): 返回查詢結果的第一個對象,返回一個普通對象(User object)

res = models.User.objects.filter(name='sgt').first() print(res) # User object

<9> last(): 返回查詢結果的最后一個對象,返回一個普通對象(User object)

res = models.User.objects.filter(name='sgt').last() print(res) # User object

<10> exists(): QuerySet方法, 如果QuerySet包含數據,就返回True,否則返回False

res = models.User.objects.filter(name='sgt').exists() print(res) # True res = models.User.objects.filter(name='sgg').exists() print(res) # False

<11> values(*field): 返回一個特殊的QuerySet對象,對象里面是一個列表套字典(model的實例化對象,而是一個可迭代的字典序列)

res = models.User.objects.filter(name='sgt').values('age') print(res) print(res.order_by('age')) print(res.order_by('age').reverse()) print(res.count()) print(res[0]) print(res.first(), res.last())<QuerySet [{'age': 18}, {'age': 32}, {'age': 22}]> # values方法返回結果 <QuerySet [{'age': 18}, {'age': 32}, {'age': 22}]> # 通過age來反向排列,無效,說明該方法只能用在order_by之后,才能進行反向排列 <QuerySet [{'age': 18}, {'age': 22}, {'age': 32}]> # order_by <QuerySet [{'age': 32}, {'age': 22}, {'age': 18}]> # order_by后再reverse 3 # 使用count方法 {'age': 18} # 可以用索引取出對應索引的字典 {'age': 18} {'age': 22} # 使用first和last方法

<12> values_list(*field): 它與values()非常相似,它返回的是一個元組序列的QuerySet對象

res = models.User.objects.filter(name='sgt').values_list('age') print(res) print(res.order_by('age')) print(res.order_by('age').reverse()) print(res.count()) print(res[0]) print(res.first(), res.last())<QuerySet [(18,), (32,), (22,)]> <QuerySet [(18,), (22,), (32,)]> <QuerySet [(32,), (22,), (18,)]> 3 (18,) (18,) (22,)結果和values方法差不多,只是把字典序列變成了元祖序列

<13> distinct(): 從返回結果中剔除重復紀錄,注意必須是所有數據都相同才滿足去重條件,但是一個表中的每一條數據是不會完全重復的,因為有primary_key的存在,就不會完全相同,所以此方法的主要是在上面的values和values_list方法的基礎上用的話會實現一些我們想要的結果。返回特殊的QuerySet對象

res1 = models.User.objects.filter(name='sgt') res2 = models.User.objects.filter(name='sgt').distinct() print(res1) print(res2) # <QuerySet [<User: User object>, <User: User object>, <User: User object>, <User: User object>]> # <QuerySet [<User: User object>, <User: User object>, <User: User object>, <User: User object>]> # 結果數量不變,說明沒有去重的項目,主要原因:id沒有相同的,肯定無法去重# 我們用values方法的基礎上使用distinct方法: res1 = models.User.objects.filter(name='sgt').values('age') res2 = res1.distinct() print(res1) print(res2)# <QuerySet [{'age': 18}, {'age': 32}, {'age': 22}, {'age': 22}]> # <QuerySet [{'age': 18}, {'age': 32}, {'age': 22}]> # 發現這樣去重的意義就出來了

只要是QuerySet對象都可以無線的點其中的方法,點下去…

包含(區分大小寫__contains|不區分大小寫__icontains),以xx開頭(__startswith),以xx結尾(__endswith)

res1 = models.User.objects.filter(name__contains='i').values('name', 'age') print(res1) # <QuerySet [{'name': 'igon', 'age': 55}, {'name': 'igoN', 'age': 66}]> res2 = models.User.objects.filter(name__contains='N').values('name', 'age') print(res2) # <QuerySet [{'name': 'igoN', 'age': 66}]> res0 = models.User.objects.filter(name__icontains='j').values('name', 'age') print(res0) # <QuerySet [{'name': 'json', 'age': 11}, {'name': 'Jason', 'age': 16}]> res3 = models.User.objects.filter(name__startswith='j').values('name', 'age') print(res3) # <QuerySet [{'name': 'json', 'age': 11}]> res4 = models.User.objects.filter(name__endswith='t').values('name', 'age') print(res4) # <QuerySet [{'name': 'sgt', 'age': 18}]>

時間為2018年的記錄:(__year=2017)

res = models.User.objects.filter(register_time__year=2018).values('name', 'age', 'register_time') print(res) # <QuerySet [{'name': 'json', 'age': 11, 'register_time': datetime.date(2018, 6, 21)}]>

在指定容器內__in=[a,b,c],在指定范圍內__range=[m,n],首尾都包括在內

res1 = models.User.objects.filter(age__in=[66, 88]).values('name', 'age') print(res1) # <QuerySet [{'name': '王大炮', 'age': 66}, {'name': '黃飛鴻', 'age': 88}, {'name': 'igoN', 'age': 66}]> res2 = models.User.objects.filter(age__range=[9, 12]).values('name', 'age') print(res2) # <QuerySet [{'name': '鐵頭', 'age': 9}, {'name': '佩奇', 'age': 12}, {'name': 'json', 'age': 11}]>

三、多表查詢

  • 表與表之間的關系
    #一對一(OneToOneField):一對一字段無論建在哪張關系表里面都可以,但是推薦建在查詢頻率比較高的那張表里面
    #一對多(ForeignKey):一對多字段建在多的那一方
    #多對多(ManyToManyField):多對多字段無論建在哪張關系表里面都可以,但是推薦建在查詢頻率比較高的那張表里面 多對多操作:
    添加add(),
    修改set(),
    移除remove() 注意不能接收可迭代對象,
    清空clear() 無需傳參

如何判斷表與表之間到底是什么關系 換位思考
A能不能有多個B
B能不能有多個A

  • 多表的增刪改查:
from django.db import models# 多表查詢示例表 class Book(models.Model):title = models.CharField(max_length=32)price = models.DecimalField(max_digits=8, decimal_places=2)publish_date = models.DateField(auto_now_add=True)# 外鍵關系# 一對多:(外鍵)publish = models.ForeignKey(to='Publish')# 多對多:author = models.ManyToManyField(to='Author') # 這是一個虛擬字段, 信號字段class Publish(models.Model):name = models.CharField(max_length=32)addr = models.CharField(max_length=32)email = models.EmailField() # 對應的就是varchar類型class Author(models.Model):name = models.CharField(max_length=32)age = models.IntegerField()# 一對一關系authordetail = models.OneToOneField(to='AuthorDetail')class AuthorDetail(models.Model):phone = models.CharField(max_length=32)addr = models.CharField(max_length=32)

增刪改:一對多
Book與Publish 一對多關系
新增:

# 一對多新增: # 由于book表和Publish表示多對一的關系,所以我們需要先建立Publish相關數據才能進行book記錄新增 models.Publish.objects.create(name='東方出版社', addr='北京', email='123@163.com') models.Publish.objects.create(name='西方出版社', addr='內蒙', email='456@163.com') models.Publish.objects.create(name='南方出版社', addr='武漢', email='789@163.com') models.Publish.objects.create(name='北方出版社', addr='上海', email='546@163.com')# 新增book記錄(直接添加寫id) models.Book.objects.create(title='西游記', price=66, publish_id=1) models.Book.objects.create(title='紅樓夢', price=266, publish_id=2) models.Book.objects.create(title='西廂記', price=166, publish_id=3) models.Book.objects.create(title='金屏梅', price=366, publish_id=4) # 一對多新增,傳輸數據對象 publish_obj = models.Publish.objects.filter(pk=1).first() models.Book.objects.create(title='三國志', price=48, publish=publish_obj)

修改:

# 一對多修改# QuerySet方法修改 ① models.Book.objects.filter(pk=1).update(publish_id=2) ② publish_obj = models.Publish.objects.filter(pk=4).first() models.Book.objects.filter(pk=1).update(publish=publish_obj)# 對象方法修改 ① book_obj = models.Book.objects.filter(pk=1).first() book_obj.publish_id = 3 # 點表中真實存在的字段名 book_obj.save() ② book_obj = models.Book.objects.filter(pk=1).first() publish_obj = models.Publish.objects.filter(pk=1).first() book_obj.publish = publish_obj book_obj.save()

刪除:(默認情況下)

# 多對一刪除 ①QuerySet方法 # 當刪除'多'的表數據,則那張'一'的表無影響 models.Book.objects.filter(pk=1).delete()# 當刪除'一'的表數據,則那張'多'的表對應的記錄會刪除 models.Publish.objects.filter(pk=2).delete()②對象方法: book_obj = models.Book.objects.filter(pk=2).first() book_obj.delete()

增刪改:多對多
book與author表之間是多對多關系
新增

# 多對多關系表的新增 # 過程:先新增數據,后綁定關系 # 先新增author數據和book數據(假設作者信息已經存在對應Detail表) models.Author.objects.create(name='蕭鼎', age=66, authordetail_id=1) models.Author.objects.create(name='路遙', age=56, authordetail_id=2) models.Author.objects.create(name='三毛', age=77, authordetail_id=3) models.Author.objects.create(name='金庸', age=95, authordetail_id=4) book_obj = models.Book.objects.create(title='畫江湖', price=99, publish_id=1) book_obj.author.add(2, 3)當然新增也支持傳對象的方式 author_obj1 = models.Author.objects.filter(pk=1).first() author_obj2 = models.Author.objects.filter(pk=2).first() book_obj.author.add(author_obj1, author_obj2)

修改

# 修改book和author記錄及其關系:set()方法,必須傳可迭代對象 book_obj = models.Book.objects.filter(pk=3).first() # 修改方法和新增類似,也是修改自身數據后再修改關系 # 可以傳數字和對象,并且也支持傳多個 # 傳id book_obj.author.set((1,)) # 傳一個 book_obj.author.set((1,2,3)) # 傳多個 # 傳對象 author_list = models.Author.objects.all() book_obj = models.Book.objects.filter(pk=3).first() book_obj.author.set(author_list)

刪除:默認情況下刪除一方表記錄,連帶的會刪除其綁定關系,但是另一邊記錄無影響,僅僅是綁定關系沒有了

# 多對多刪除 # QuerySet方法 models.Book.objects.filter(pk=4).delete() # 刪除id為4的書,同時會自動刪除此書與作者之間的關系,此時綁定關系會自動刪除# 對象方法 book_obj = models.Book.objects.filter(pk=5).first() book_obj.author.remove(2) # 先刪除關系不會刪除book記錄數據book_obj = models.Book.objects.filter(pk=6).first() book_obj.delete() # 刪除book對象,會自動觸發刪除綁定關系# 假設一本書有多個作者 book_obj = models.Book.objects.filter(pk=1).first() author_list = models.Author.objects.all() book_obj.author.remove(*author_list) # 注意這里的QuerySet需要打散才行

增刪改:一對一

# 一對一,author表創建外鍵綁定關系到authordetail表,刪除創建外鍵的那張author表的記錄,另一方無影響 models.Author.objects.filter(pk=1).delete() # 一對一,刪除非外鍵的那張authordetail表記錄,則綁定關系以及對應的author表記錄都會隨之刪除 models.AuthorDetail.objects.filter(pk=2).delete()

新增:

# 一對一新增:創建外鍵的表author中新增記錄,對應的外鍵必須未用占且存在,因為是一對一關系,否則報錯 models.Author.objects.create(name='王錘', age=88, authordetail_id=1) # 一對一新增,authordetail表中新增記錄,author表無影響. models.AuthorDetail.objects.create(phone='123', addr='毛里求斯')

修改:

# 一對一修改, models.Author.objects.filter(pk=8).update(name='湯勺') models.AuthorDetail.objects.filter(pk=4).update(addr='伊拉克')# 一對一修改 關聯外鍵值: # 外鍵值必須未占用,且存在,不然報錯 models.Author.objects.filter(pk=8).update(authordetail_id=5)

清空clear()

book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.clear() # 清空當前書籍對應的所有作者的綁定關系

正向查詢:通過一張表a查詢另一張表b,如果a與b之間的關系外鍵是建在a中,那么我們從a中能通過這個外鍵字段查詢到b表中的對應數據的過程就叫做正向查詢
反向查詢:上面的正向查詢,如果從b表去找a表的數據,外鍵還是建在a表中,這時候b表中就沒有與a表關聯的字段,此時b查到a就需要用另外的手段來實現,這種就叫反向查詢
正向、反向查詢方法:
原則:正向查詢按字段,反向查詢按表名小寫

一對一

Author表和AuthorDetail表是一對一關系:(外鍵在Author表中)

## 正向查詢:從Author查到AuthorDetail: res = models.Author.objects.filter(pk=3).first().authordetail.addr print(res) # 冥王星## 反向查詢:從AuthorDetail 查到Author res1 = models.AuthorDetail.objects.filter(pk=3).first().author.name print(res1) # 三毛

一對多

# Book到Publish res = models.Book.objects.filter(pk=1).first().publish.name print(res) # 東方出版社# Publish到Book res1 = models.Publish.objects.filter(pk=2).first().book_set.all() print(res1) # <QuerySet [<Book: Book object>, <Book: Book object>]> res2 = models.Publish.objects.filter(pk=2).first().book_set.all().values('title') print(res2) # <QuerySet [{'title': '紅樓夢'}, {'title': '西游記'}]>

#多對多

# 正向查詢 res1 = models.Book.objects.filter(pk=2).first().author.all() print(res1) # <QuerySet [<Author: Author object>, <Author: Author object>]> res2 = models.Book.objects.filter(pk=2).first().author.all().values('name') print(res2) # <QuerySet [{'name': '金庸'}, {'name': '湯勺'}]> # 反向查詢 res3 = models.Author.objects.filter(pk=3).first().book_set.all() print(res3) # <QuerySet [<Book: Book object>, <Book: Book object>]> res4 = models.Author.objects.filter(pk=3).first().book_set.all().values('title') print(res4) # <QuerySet [{'title': '西廂記'}, {'title': '紅樓夢'}]>

規律:一對多、多對多 反向查詢的時候要加_set.all()
一對一 反向查詢不用加

基于雙下劃線的多表查詢

用例子來說明:
① 查詢書籍為紅樓夢的出版社名:

res = models.Book.objects.filter(title='紅樓夢').values('publish__name') print(res) # <QuerySet [{'publish__name': '南方出版社'}]>

② 查詢書籍為西游記的作者的姓名:

res = models.Book.objects.filter(title='西游記').values('author__name') print(res) # <QuerySet [{'author__name': '三毛'}, {'author__name': '唐唐'}]>

③ 查詢南方出版社初版的書名:

res = models.Publish.objects.filter(name='南方出版社').values('book__title') print(res) # <QuerySet [{'book__title': '紅樓夢'}, {'book__title': '西游記'}]>

④ 查詢電話號碼是911的作者寫的書名:

res = models.AuthorDetail.objects.filter(phone='911').values('author__book__title') print(res) # <QuerySet [{'author__book__title': '三國志'}, {'author__book__title': '西廂記'}]>

⑤ 查詢作者名字為金庸寫的書的書名:

res = models.Author.objects.filter(name='金庸').values('book__title') print(res) # <QuerySet [{'book__title': '三國志'}, {'book__title': '西廂記'}]>

⑥ 查詢書籍為西游記的作者的電話號碼:

res = models.Book.objects.filter(title='西游記').values('author__name', 'author__authordetail__phone') print(res) # <QuerySet [{'author__name': '三毛', 'author__authordetail__phone': '119'}, # {'author__name': '唐唐', 'author__authordetail__phone': '110'}]>

⑦ 通過作者細節表 查詢作者叫金庸的電話號碼

res = models.AuthorDetail.objects.filter(author__name='金庸').values('phone') print(res) # <QuerySet [{'phone': '911'}]>

⑧ 從書這張表 查詢出版社為南方出版社的所有圖書的名字和價格

res = models.Book.objects.filter(publish__name='南方出版社').values('title', 'price') print(res) # <QuerySet [{'title': '紅樓夢', 'price': Decimal('67.00')}, {'title': '西游記', 'price': Decimal('87.00')}]>

⑨ 查詢東方出版社初版的書的價格大于45的書

res = models.Publish.objects.filter(name='東方出版社', book__price__gt=45).values('book__title', 'book__price') print(res) # <QuerySet [{'book__title': '三國志', 'book__price': Decimal('48.00')}]>

四、聚合查詢和分組查詢

  • 聚合查詢 aggregate(),它是QuerySet的一個終止子句,意思就是,會返回一個包含一些鍵值對的字典
    鍵的名稱是聚合值的標識符,值是計算出來的聚合值。鍵的名稱是按照字段和聚合函數的名稱自動生成出來的 用到的內置函數:
from django.db.models import Avg, Sum, Max, Min, Count

示例:

from django.db.models import Avg,Sum,Max,Min,Count、 查詢所有書籍的平均價格,最大價格,書的數量 res = models.Book.objects.all().aggregate(Avg('price'), Max('price'), Count('title')) print(res) # {'price__avg': 56.6, 'price__max': Decimal('87.00'), 'title__count': 5}

可以給聚合值指定一個名稱,用于使用該聚合值

如果你想要為聚合值指定一個名稱,可以向聚合子句提供它。>>> models.Book.objects.aggregate(average_price=Avg('price')) {'average_price': 13.233333}
  • 分組查詢 示例: 統計每一個出版社的出版的書平均價格
res = models.Publish.objects.annotate(avg_price=Avg('book__price')).values('name', 'avg_price') print(res) # <QuerySet [{'name': '東方出版社', 'avg_price': 46.0}, {'name': '南方出版社', 'avg_price': 77.0}, {'name': '北方出版社', 'avg_price': 37.0}]>


統計出每個出版社買的最便宜的書的價格

# <QuerySet [{'name': '東方出版社', 'avg_price': 46.0}, {'name': '南方出版社', 'avg_price': 77.0}, {'name': '北方出版社', 'avg_price': 37.0}]> res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name', 'min_price' ) print(res) # <QuerySet [{'name': '東方出版社', 'min_price': Decimal('44.00')}, {'name': '南方出版社', 'min_price': Decimal('67.00')}, {'name': '北方出版社', 'min_price': Decimal('37.00')}]>

統計不止一個作者的圖書

res = models.Book.objects.annotate(author_num=Count('author')).filter(author_num__gt=1).values('title') print(res)# <QuerySet [{'title': '西廂記'}]>

總結

以上是生活随笔為你收集整理的Web框架之Django_05 模型层了解(单表查询、多表查询、聚合查询、分组查询)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。