前期準備:git
建立表sql
class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) publish_time = models.DateField(auto_now_add=True) #該字段新增數據會自動添加實時時間 #出版社 一對多 外鍵字段建在多的一方 publish = models.ForeignKey(to='Publish') #做者 多對多 外鍵字段推薦建在查詢頻率較高的表 authors = models.ManyToManyField(to='Author') class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=64) class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() #做者詳情 一對一 外鍵字段推薦建在查詢頻率較高的表 author_detail = models.OneToOneField(to='AuthorDetail') class AuthorDetail(models.Model): phone = models.BigIntegerField() addr = models.CharField(max_length=32)
外鍵字段在1.X版本中默認就是級聯更新級聯刪除
2.X版本中則須要手動指定(百度)django
增:app
# 增 方式1 直接寫實際的表字段 publish_id models.Book.objects.create(title='三國',price='123.12',publish_id=2) # 增 方式2 publish_obj = models.Publish.objects.get(pk=1) models.Book.objects.create(title='水滸傳',price=66,publish=publish_obj)
改:ide
# 改 方式1 models.Book.objects.filter(pk=1).update(publish_id=3) # 改 方式2 publish_obj = models.Publish.objects.get(pk=4) models.Book.objects.filter(pk=1).update(publish=publish_obj)
add:spa
#1.給書籍和做者綁定關係 add """ add專門給第三張關係表添加數據 括號內便可以傳數字也能夠傳對象 而且都支持傳多個 """ book_obj = models.Book.objects.filter(pk=1).first() # 書籍和做者的關係是由第三張表決定 也就意味着你須要操做第三張表 # 書籍對象點虛擬字段authors就相似於已經跨到書籍和做者的第三張關係表中 # print(book_obj.authors) #app01.Author.None # 方式一 book_obj.authors.add(1) #給書籍綁定一個主鍵爲1的做者 book_obj.authors.add(2,3) # 方式二 author_obj = models.Author.objects.get(pk=2) author_obj1 = models.Author.objects.get(pk=3) book_obj.authors.add(author_obj) book_obj.authors.add(author_obj,author_obj1)
remove:code
# 2.移除書籍與做者的綁定關係 remove """ remove專門給第三張關係表移除數據 括號內便可以傳數字也能夠傳對象 而且都支持傳多個 """ book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.remove(2) book_obj.authors.remove(1,3) # author_obj = models.Author.objects.get(pk=2) # author_obj1 = models.Author.objects.get(pk=3) # book_obj.authors.remove(author_obj) # book_obj.authors.remove(author_obj,author_obj1)
set:orm
# 3 修改書籍與做者的關係 set """ set 修改書籍與做者的關係 括號內支持傳數字和對象 可是須要是可迭代對象 """ book_obj = models.Book.objects.filter(pk=1).first() # book_obj.authors.set((3,)) book_obj.authors.set((2, 3)) author_obj = models.Author.objects.get(pk=2) author_obj1 = models.Author.objects.get(pk=3) book_obj.authors.set((author_obj,)) book_obj.authors.set([author_obj,author_obj1])
clear:對象
# 4 清空書籍與做者關係 """ clear() 清空關係 不須要任何的參數 """ book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.clear() # 去第三張表中清空書籍爲1的全部數據
跨表查詢的方式
1.子查詢 將一張表的查詢結果當作另一張表的查詢條件
2.鏈表查詢
建議:在寫sql語句或者orm語句的時候,千萬不要想着一次性將語句寫完,必定要寫一點查一點blog
正反向的概念
正向
跨表查詢的時候,看外鍵字段是否在當前數據對象中,若是在的話,查詢另一張關係表 叫正向
反向
若是不在叫反向
口訣
正向查詢按外鍵字段
反向查詢按表名小寫 看狀況加_set
#正向: # 1.查詢書籍pk爲1的出版社名稱 book_obj = models.Book.objects.filter(pk=1).first() #先拿到書籍對象 print(book_obj.publish) #書籍對象點外鍵字段拿到的是出版社對象 print(book_obj.publish.name) print(book_obj.publish.addr) # 2.查詢書籍pk爲2的全部做者的姓名 book_obj = models.Book.objects.filter(pk=2).first() # print(book_obj.authors) # app01.Author.None print(book_obj.authors.all()) #<QuerySet [<Author: Author object>]> author_list = book_obj.authors.all() for author_obj in author_list: print(author_obj.name) # 3.查詢做者hank的電話號碼 author_obj = models.Author.objects.filter(name='hank').first() print(author_obj.author_detail) print(author_obj.author_detail.phone) """ 正向查詢的時候 當外鍵字段對應的數據能夠有多個的時候須要加.all() 不然點外鍵字典便可獲取到對應的數據對象 """ #反向 # 3.查詢做者hank的電話號碼 author_obj = models.Author.objects.filter(name='hank').first() print(author_obj.author_detail) print(author_obj.author_detail.phone) # 4.查詢出版社名稱爲東方出版社出版過的書籍 publish_obj = models.Publish.objects.filter(name='東方出版社').first() print(publish_obj.book_set) #app01.Book.None print(publish_obj.book_set.all()) #<QuerySet [<Book: Book object>]> # 5.查詢做者hank寫過的書 author_obj = models.Author.objects.filter(name='hank').first() print(author_obj.book_set) # app01.Book.None print(author_obj.book_set.all()) # 6.查詢手機號爲120的做者姓名 author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first() print(author_detail_obj.author.name) """ 基於對象的反向查詢 表名小寫是否須要加_set.all()? 一對多和多對多的時候須要加 一對一不須要 """
注意:只要表之間有關係,你就能夠經過正向的外鍵字段或者反向的表名小寫,連續跨表操做
# 1.查詢書籍pk爲1的出版社名稱 # 正向 res = models.Book.objects.filter(pk=1).values('publish__name') # 寫外鍵字段 就意味着你已經在外鍵字段管理的那張表中 print(res) #<QuerySet [{'publish__name': '西方出版社'}]> # 反向 res = models.Publish.objects.filter(book__pk=1).first() # 拿出版過pk爲1的書籍對應的出版社 print(res.name) #西方出版社 # 2.查詢書籍pk爲1的做者姓名和年齡 # 正向 res = models.Book.objects.filter(pk=1).values('title','authors__name','authors__age') print(res) # 反向 # res = models.Author.objects.filter(book__pk=1) # 拿出出版過書籍pk爲1的做者 res = models.Author.objects.filter(book__pk=1).values('name','age') print(res) # 3.查詢做者是hank的年齡和手機號 # 正向 res = models.Author.objects.filter(name='hank').values('age','author_detail__phone') print(res) # 反向 # res = models.AuthorDetail.objects.filter(author__name='hank') #拿到hank的我的詳情 res = models.AuthorDetail.objects.filter(author__name='hank').values('phone','author__age') print(res) # 4.查詢書籍pk爲的1的做者的手機號 # 正向 res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone') print(res) #<QuerySet [{'authors__author_detail__phone': 120}]> # 反向 res = models.AuthorDetail.objects.filter(author__book__pk=1).values('phone') print(res) #<QuerySet [{'phone': 120}]>
關鍵字:aggregate
from django.db.models import Max,Min,Avg,Count,Sum
# 查詢全部書的平均價格 res = models.Book.objects.aggregate(Avg('price')) print(res) # 查詢價格最貴的書 res = models.Book.objects.aggregate(Max('price')) print(res) #查詢書的總數 res = models.Book.objects.aggregate(Count("pk")) print(res) # 查詢全部書的總價 res = models.Book.objects.aggregate(Sum('price')) print(res)
關鍵字:annotate
# 1.統計每一本書的做者個數 res = models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num') print(res) # 2.統計出每一個出版社賣的最便宜的書的價格 res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price','book__title') print(res) # 3.統計不止一個做者的圖書 res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title') print(res) # 4.查詢各個做者出的書的總價格 res = models.Author.objects.annotate(price_sum=Sum('book__price')).values('name','price_sum') print(res) # 5.如何按照表中的某一個指定字段分組 """ res = models.Book.objects.values('price').annotate() 就是以價格分組 """