<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
moduls.py
# 構建表結構 from django.db import models # 表app01_publish class Publish(models.Model): name = models.CharField(max_length=20) addr = models.CharField(max_length=20) # 表app01_author_detail class Author_Detail(models.Model): tel = models.CharField(max_length=20) # 表app01_author class Author(models.Model): name = models.CharField(max_length=20) age = models.IntegerField() # 表app01_author一對一表app01_authordetail detail = models.OneToOneField(to='Author_Detail',to_field='id',unique=True,on_delete=models.CASCADE) # 表app01_book class Book(models.Model): title = models.CharField(max_length=20) price = models.DecimalField(max_digits=8, decimal_places=2) pub_date = models.DateField(auto_now_add=True) # 表app01_book多對一表app01_publish,引數to指定模型名,引數to_field指定要關聯的那個欄位 publish = models.ForeignKey(to='Publish',to_field='id',on_delete=models.CASCADE) # 我們自己寫sql時,針對書籍表與作者表的多對關係,需要自己建立新表,而基於django的orm,下面這一行程式碼可以幫我們自動建立那張關係表 authors=models.ManyToManyField(to='Author') # 變數名為authors,則新表名為app01_book_authors,若變數名為xxx,則新表名為app01_book_xxx
tests.py
# 新增資料 import os if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "book_sys.settings") import django django.setup() from app01.models import * # 1、先新增沒有外來鍵欄位的 author_detail表 pubulish表 Author_Detail.objects.create(tel='123456789') Author_Detail.objects.create(tel='987654321') Author_Detail.objects.create(tel='000000000') Publish.objects.create(name='北方出版社',addr='北京') Publish.objects.create(name='南方出版社',addr='南京') Publish.objects.create(name='東方出版社',addr='上海') Publish.objects.create(name='西方出版社',addr='西安') # 2、新增 author表 book表 Author.objects.create(name='frank',age=31 ,detail_id=1) Author.objects.create(name='lili',age=29 ,detail_id=2) Author.objects.create(name='tank',age=42 ,detail_id=3) Book.objects.create(title='三國演義',price=200 ,publish_id=1) Book.objects.create(title='三國志',price=198.5 ,publish_id=2) Book.objects.create(title='紅樓夢',price=255.43 ,publish_id=2) Book.objects.create(title='西遊記',price=300.5 ,publish_id=3) Book.objects.create(title='西廂記',price=213.4 ,publish_id=4) Book.objects.create(title='水滸傳',price=199 ,publish_id=1) # 3、最後操作 author_book表,由於使用的是 ManyToMany 欄位自動生成的,所以要基於外來鍵所在的表進行操作 book_obj1=Book.objects.filter(pk=1).first() book_obj1.authors.add(1,2) book_obj2 = Book.objects.filter(pk=2).first() book_obj2.authors.add(1) book_obj3 = Book.objects.filter(pk=3).first() author_obj1 = Author.objects.filter(pk=1).first() author_obj2 = Author.objects.filter(pk=2).first() book_obj3.authors.add(author_obj1,author_obj2) book_obj4 = Book.objects.filter(pk=4).first() book_obj4.authors.add(3,2) book_obj5 = Book.objects.filter(pk=5).first() book_obj5.authors.add(3) book_obj6 = Book.objects.filter(pk=6).first() book_obj6.authors.add(1,3)
一出版社和書籍為例, 書記表含有出版社表的外來鍵欄位
正向查詢>>> 書籍查詢出版社
反向查詢>>> 出版社查詢書籍
總結: 當前查詢物件是否含有外來鍵欄位, 有就是正向查詢, 沒有就是反向查詢
正向查詢按照欄位查詢, 反向查詢按照表名查詢
相當於MySQL中的子查詢: 將一張表的查詢結果用括號括起來, 當作另一條SQL語句的條件 .
查詢書籍主鍵為5 的出版社名稱
1. 查主鍵為5的書籍物件
2. 根據書籍物件的外來鍵欄位 publish 獲取到出版社物件
3. 由出版社物件獲取到名稱
book_obj = Book.objects.filter(pk=5).first() res = book_obj.publish print(res) # Publish object print(res.name) # 西方出版社
查詢書籍主鍵為3的作者姓名
1. 查詢書籍主鍵為3的書籍物件
2. 外來鍵欄位在書籍表中, 同樣是正向查詢,那麼只需要按照欄位autjors查詢即可
3. 獲取作者物件的姓名
book_obj = Book.objects.filter(pk=3).first() res = book_obj.authors print(res) # app01.Author.None
注意: 由於欄位authors 是多對多的外來鍵欄位, 此時拿到的物件還需要進一步的操作
book_obj = Book.objects.filter(pk=3).first() res = book_obj.authors res1 = book_obj.authors.all() print(res1) # <QuerySet [<Author: Author object>, <Author: Author object>]>
然後再for迴圈各自的姓名即可
查詢作者lili的號碼
1.查詢作者物件
2,外來鍵欄位再作者表中, 同樣是正向查詢,那麼只需要按照字典detail查詢即可
3. 獲取詳情物件的tel
author_obj = Author.objects.filter(name='lili').first() res = author_obj.detail print(res) print(res.tel)
查詢東方出版社出版的書籍
1. 先獲取東方出版社的物件
2. 出版社沒有外來鍵欄位, 去查書籍是反向查詢
3. 表名小寫_set.all()
4. 獲取書籍名稱
publish_obj=Publish.objects.filter(name='東方出版社').first() print(publish_obj) # Publish object res = publish_obj.book_set print(res) # app01.Book.None res1 = res.all() print(res1) # <QuerySet [<Book: Book object>]> for obj in res1: print(obj.title)
查詢作者lili寫過的書籍
1.獲取作者物件
2. 作者表中沒有書籍表的外來鍵, 所以是反向查詢
3. .book_set.all()獲取書籍物件
4. 再獲取書籍物件的名稱
author_obj = Author.objects.filter(name='lili').first() res = author_obj.book_set print(res) # app01.Book.None res1 = res.all() print(res1) # <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>]> for obj in res1: print(obj.title, end='') # 三國演義,紅樓夢,西遊記,
查詢號碼為0000000的作者
1. 查詢作者物件詳情
2.外來鍵欄位在作者表中, 同樣是證詞昂查詢, 那麼只需要按照欄位detail 查詢即可
3. 獲取詳情物件的tel
detail_obj = Author_Detail.objects.filter(tel='000000000').first() print(detail_obj) # Author_Detail object res = detail_obj.author print(res) # Author object print(res.name) # tank
方法總結
一對一, 一對多的方法是一樣的, 按照欄位查詢就能夠直接找到物件 --- author_obj.detail
一對多 , 按照欄位查詢後會返回一個.None的物件, 需要在欄位後面加上.all()>>> book_obj.authors.all()
一對多,多對多的方法是一樣的, 按照表名小寫, 在跟上_set.all()>>>author_obj.book_set.all()
一對一, 則直接按照表明小寫, 能夠直接拿到>> > detail_obj.author
當查詢到的結果中最後以.None結尾, 都需要在原來的查詢方法後面在跟上.all()才能獲得想要的結果
相當於MySQL中的連表查詢: 將兩張表或者對賬表連成一張表進行查詢
正向查詢, 按照關聯欄位+雙下線>>> .values('關聯欄位__被關聯表中的欄位'), 返回的是一個QuerySet物件
查詢作者frank的手機號
res = Author.objects.filter(name='frank').values('detail__tel') print(res) # <QuerySet [{'detail__tel': '123456789'}]> print(res.first()) # {'detail__tel': '123456789'}
查詢三國演義的出版社名字
res = Book.objects.filter(title='三國演義').values('publish__name') print(res) print(res.first()) # <QuerySet [{'publish__name': '北方出版社'}]> # {'publish__name': '北方出版社'}
查詢三國演義的所有作者
res = Book.objects.filter(title='三國演義').values('authors__name') print(res) # <QuerySet [{'authors__name': 'frank'}, {'authors__name': 'lili'}]>
按模型名(小寫)+雙下線>>> .values('表名小寫__被關聯表中的欄位'), 返回的是一個QuerySet物件.
查詢手機號為'123456789'的作者名
res = Author_Detail.objects.filter(tel='123456789').values('author__name') print(res) # <QuerySet [{'author__name': 'frank'}]>
查詢北方出版社出版的所有書籍名字
res = Publish.objects.filter(name='北方出版社').values('book__title') print(res) # <QuerySet [{'book__title': '三國演義'}, {'book__title': '水滸傳'}]>
多對多
查詢lili出版的所有書籍
res = Author.objects.filter(name='lili').values('book__title') print(res) # <QuerySet [{'book__title': '三國演義'}, {'book__title': '紅樓夢'}, {'book__title': '西遊記'}]>
方法總結:
正向查詢,按關聯欄位: .values('關聯欄位__被關聯表中的欄位'), 返回的是一個QuerySet物件
按模型名(小寫)+雙下線: .values('表名小寫__被關聯表中的欄位'), 返回的是一個QuerySet物件, 物件中儲存的是字典型別的資料
首先需要考慮的是正向查詢還是反向查詢, 確定括號內使用的方法, 但是括號外面不是使用values,而是使用filter!!!
注意: 使用filter方法欄位是不能加引號的, values需要加引號
查詢書籍主鍵為反向, 使用.filter('表名小寫__被關聯表中的欄位')
res = Publish.objects.filter(book__pk= 4) print(res) # <QuerySet [<Publish: Publish object>]> res = Publish.objects.filter(book__title= '西遊記') print(res) # 結果相同
套路與上面的案例都是一樣的, 可以練習n個雙下劃線, 只需要在每次雙下線的時候, 確定是每個雙下線後面是正向查詢還是反向查詢即可
# 需求1:查詢北京出版社出版過的所有書籍的名字以及作者的姓名、手機號 # 方式一:基表為Publish res=Publish.objects.filter(name='北方出版社').values_list('book__title','book__authors__name','book__authors__author_detail__tel') # 方式二:基表為Book res=Book.objects.filter(publish__name='北方出版社').values_list('title','authors__name','authors__author_detail__tel') # 迴圈列印結果均為 for obj in res: print(obj) # 需求2:查詢手機號以186開頭的作者出版過的所有書籍名稱以及出版社名稱 # 方式一:基表為AuthorDetail res=AuthorDetail.objects.filter(tel__startswith='186').values_list('author__book__title','author__book__publish__name') # 方式二:基表為Book res=Book.objects.filter(authors__author_detail__tel__startswith='186').values_list('title','publish__name') # 方式三:基表為Publish res=Publish.objects.filter(book__authors__author_detail__tel__startswith='186').values_list('book__title','name') # 迴圈列印結果均為 for obj in res: print(obj)
到此這篇關於Django ORM 多表查詢的文章就介紹到這了,更多相關Django ORM 多表查詢內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45