Django教程Django ORM - 單表實例Django ORM – 多表實例https://www.runoob.com/django/django-orm-2.html Django ORM – 多表實例表與表之間的關(guān)系可分為以下三種:
創(chuàng)建模型接下來我們來看下多表多實例,。 實例class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) pub_date = models.DateField() publish = models.ForeignKey("Publish", on_delete=models.CASCADE) authors = models.ManyToManyField("Author") class Publish(models.Model): name = models.CharField(max_length=32) city = models.CharField(max_length=64) email = models.EmailField() class Author(models.Model): name = models.CharField(max_length=32) age = models.SmallIntegerField() au_detail = models.OneToOneField("AuthorDetail", on_delete=models.CASCADE) class AuthorDetail(models.Model): gender_choices = ( (0, "女"), (1, "男"), (2, "保密"), ) gender = models.SmallIntegerField(choices=gender_choices) tel = models.CharField(max_length=32) addr = models.CharField(max_length=64) birthday = models.DateField() 說明:
表結(jié)構(gòu)書籍表 Book:title ,、 price 、 pub_date ,、 publish(外鍵,,多對一) 、 authors(多對多) 出版社表 Publish:name ,、 city ,、 email 作者表 Author:name 、 age ,、 au_detail(一對一) 作者詳情表 AuthorDetail:gender ,、 tel ,、 addr 、 birthday 以下是表格關(guān)聯(lián)說明: 插入數(shù)據(jù)我們在 MySQL 中執(zhí)行以下 SQL 插入操作: insert into app01_publish(name,city,email) values ("華山出版社", "華山", "[email protected]"), ("明教出版社", "黑木崖", "[email protected]") # 先插入 authordetail 表中多數(shù)據(jù)insert into app01_authordetail(gender,tel,addr,birthday) values (1,13432335433,"華山","1994-5-23"), (1,13943454554,"黑木崖","1961-8-13"), (0,13878934322,"黑木崖","1996-5-20") # 再將數(shù)據(jù)插入 author,,這樣 author 才能找到 authordetail insert into app01_author(name,age,au_detail_id) values ("令狐沖",25,1), ("任我行",58,2), ("任盈盈",23,3) ORM - 添加數(shù)據(jù)一對多(外鍵 ForeignKey)方式一: 傳對象的形式,,返回值的數(shù)據(jù)類型是對象,書籍對象,。 步驟:
app01/views.py 文件代碼:def add_book(request): # 獲取出版社對象 pub_obj = models.Publish.objects.filter(pk=1).first() # 給書籍的出版社屬性publish傳出版社對象 book = models.Book.objects.create(title="菜鳥教程", price=200, pub_date="2010-10-10", publish=pub_obj) print(book, type(book)) return HttpResponse(book) 方式二: 傳對象 id 的形式(由于傳過來的數(shù)據(jù)一般是 id,所以傳對象 id 是常用的),。 一對多中,設(shè)置外鍵屬性的類(多的表)中,,MySQL 中顯示的字段名是:外鍵屬性名_id,。 返回值的數(shù)據(jù)類型是對象,書籍對象,。 步驟:
app01/views.py 文件代碼:def add_book(request): # 獲取出版社對象 pub_obj = models.Publish.objects.filter(pk=1).first() # 獲取出版社對象的id pk = pub_obj.pk # 給書籍的關(guān)聯(lián)出版社字段 publish_id 傳出版社對象的id book = models.Book.objects.create(title="沖靈劍法", price=100, pub_date="2004-04-04", publish_id=pk) print(book, type(book)) return HttpResponse(book) 多對多(ManyToManyField):在第三張關(guān)系表中新增數(shù)據(jù)方式一: 傳對象形式,,無返回值。 步驟:
app01/views.py 文件代碼:def add_book(request): # 獲取作者對象 chong = models.Author.objects.filter(name="令狐沖").first() ying = models.Author.objects.filter(name="任盈盈").first() # 獲取書籍對象 book = models.Book.objects.filter(title="菜鳥教程").first() # 給書籍對象的 authors 屬性用 add 方法傳作者對象 book.authors.add(chong, ying) return HttpResponse(book) 方式二: 傳對象id形式,,無返回值,。 步驟:
app01/views.py 文件代碼:def add_book(request): # 獲取作者對象 chong = models.Author.objects.filter(name="令狐沖").first() # 獲取作者對象的id pk = chong.pk # 獲取書籍對象 book = models.Book.objects.filter(title="沖靈劍法").first() # 給書籍對象的 authors 屬性用 add 方法傳作者對象的id book.authors.add(pk) 關(guān)聯(lián)管理器(對象調(diào)用)前提:
語法格式: 正向:屬性名反向:小寫類名加 _set 注意:一對多只能反向 常用方法: add():用于多對多,,把指定的模型對象添加到關(guān)聯(lián)對象集(關(guān)系表)中,。 注意:add() 在一對多(即外鍵)中,只能傳對象( *QuerySet數(shù)據(jù)類型),,不能傳 id(*[id表]),。 *[ ] 的使用: # 方式一:傳對象 book_obj = models.Book.objects.get(id=10) author_list = models.Author.objects.filter(id__gt=2) book_obj.authors.add(*author_list) # 將 id 大于2的作者對象添加到這本書的作者集合中 # 方式二:傳對象 id book_obj.authors.add(*[1,3]) # 將 id=1 和 id=3 的作者對象添加到這本書的作者集合中 return HttpResponse("ok") 反向:小寫表名_set ying = models.Author.objects.filter(name="任盈盈").first() book = models.Book.objects.filter(title="沖靈劍法").first() ying.book_set.add(book) return HttpResponse("ok") create():創(chuàng)建一個新的對象,并同時將它添加到關(guān)聯(lián)對象集之中,。 返回新創(chuàng)建的對象,。 pub = models.Publish.objects.filter(name="明教出版社").first() wo = models.Author.objects.filter(name="任我行").first() book = wo.book_set.create(title="吸星大法", price=300, pub_date="1999-9-19", publish=pub) print(book, type(book)) return HttpResponse("ok") remove():從關(guān)聯(lián)對象集中移除執(zhí)行的模型對象。 對于 ForeignKey 對象,,這個方法僅在 null=True(可以為空)時存在,,無返回值。 實例author_obj =models.Author.objects.get(id=1) book_obj = models.Book.objects.get(id=11) author_obj.book_set.remove(book_obj) return HttpResponse("ok") clear():從關(guān)聯(lián)對象集中移除一切對象,,刪除關(guān)聯(lián),,不會刪除對象。 對于 ForeignKey 對象,,這個方法僅在 null=True(可以為空)時存在,。 無返回值。 # 清空獨孤九劍關(guān)聯(lián)的所有作者 book = models.Book.objects.filter(title="菜鳥教程").first() book.authors.clear() ORM 查詢基于對象的跨表查詢,。 正向:屬性名稱反向:小寫類名_set 一對多查詢主鍵為 1 的書籍的出版社所在的城市(正向),。 實例book = models.Book.objects.filter(pk=10).first() res = book.publish.city print(res, type(res)) return HttpResponse("ok") 查詢明教出版社出版的書籍名(反向)。 反向:對象.小寫類名_set(pub.book_set) 可以跳轉(zhuǎn)到關(guān)聯(lián)的表(書籍表)。 pub.book_set.all():取出書籍表的所有書籍對象,,在一個 QuerySet 里,,遍歷取出一個個書籍對象。 實例pub = models.Publish.objects.filter(name="明教出版社").first() res = pub.book_set.all() for i in res: print(i.title) return HttpResponse("ok") 一對一查詢令狐沖的電話(正向) 正向:對象.屬性 (author.au_detail) 可以跳轉(zhuǎn)到關(guān)聯(lián)的表(作者詳情表) 實例author = models.Author.objects.filter(name="令狐沖").first() res = author.au_detail.tel print(res, type(res)) return HttpResponse("ok") 查詢所有住址在黑木崖的作者的姓名(反向),。 一對一的反向,,用 對象.小寫類名 即可,不用加 _set,。 反向:對象.小寫類名(addr.author)可以跳轉(zhuǎn)到關(guān)聯(lián)的表(作者表),。 實例addr = models.AuthorDetail.objects.filter(addr="黑木崖").first() res = addr.author.name print(res, type(res)) return HttpResponse("ok") 多對多菜鳥教程所有作者的名字以及手機號(正向)。 正向:對象.屬性(book.authors)可以跳轉(zhuǎn)到關(guān)聯(lián)的表(作者表),。 作者表里沒有作者電話,,因此再次通過對象.屬性(i.au_detail)跳轉(zhuǎn)到關(guān)聯(lián)的表(作者詳情表)。 實例book = models.Book.objects.filter(title="菜鳥教程").first() res = book.authors.all() for i in res: print(i.name, i.au_detail.tel) return HttpResponse("ok") 查詢?nèi)挝倚谐鲞^的所有書籍的名字(反向),。 實例author = models.Author.objects.filter(name="任我行").first() res = author.book_set.all() for i in res: print(i.title) return HttpResponse("ok") 基于雙下劃線的跨表查詢正向:屬性名稱__跨表的屬性名稱 反向:小寫類名__跨表的屬性名稱一對多查詢菜鳥出版社出版過的所有書籍的名字與價格,。 實例res = models.Book.objects.filter(publish__name="菜鳥出版社").values_list("title", "price") 反向:通過 小寫類名__跨表的屬性名稱(book__title,book__price) 跨表獲取數(shù)據(jù),。 實例res = models.Publish.objects.filter(name="菜鳥出版社").values_list("book__title","book__price") return HttpResponse("ok") 多對多查詢?nèi)挝倚谐鲞^的所有書籍的名字,。 正向:通過 屬性名稱__跨表的屬性名稱(authors__name) 跨表獲取數(shù)據(jù): res = models.Book.objects.filter(authors__name="任我行").values_list("title") 反向:通過 小寫類名__跨表的屬性名稱(book__title) 跨表獲取數(shù)據(jù): res = models.Author.objects.filter(name="任我行").values_list("book__title") 一對一查詢?nèi)挝倚械氖謾C號,。 正向:通過 屬性名稱__跨表的屬性名稱(au_detail__tel) 跨表獲取數(shù)據(jù),。 res = models.Author.objects.filter(name="任我行").values_list("au_detail__tel") 反向:通過 小寫類名__跨表的屬性名稱(author__name) 跨表獲取數(shù)據(jù),。 res = models.AuthorDetail.objects.filter(author__name="任我行").values_list("tel") |
|