Django多表ORM設計規則
1.關聯的表之間建議創建外鍵,可是能夠取消關聯關係(db_constraint=False)git
2.關聯表之間的外鍵字段建議採用對應類名的全小寫django
3.採用關聯表的主鍵或對象都可以進行操做ide
建立models:

from django.db import models # Create your models here. class Book(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=20) price = models.DecimalField(max_digits=5, decimal_places=2) publish = models.ForeignKey(to='Publish', to_field='id') author = models.ManyToManyField(to='Author') publish_date = models.DateField() class Publish(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) address = models.CharField(max_length=32) class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) class AuthorDetail(models.Model): id = models.AutoField(primary_key=True) age = models.IntegerField() sex = models.CharField(max_length=10, default='male') author = models.OneToOneField(to='Author')
一對多關係(增刪改)
注:1.關係中,多依賴於一;2.外鍵關聯默認有級聯刪除,須要手動明確外鍵的級聯刪除(on_delete=models.CASCADE)spa
# 一、增 # 主鍵操做 publish = Publish.objects.create(name='小女孩出版社', address='山東') publish_id = publish.id Book.objects.create(name='死亡Python', price=66.66, publish_date='2018-8-8', publish_id=publish_id) # 對象操做 publish = Publish.objects.first() Book.objects.create(name='資治通鑑', price=888.88, publish_date='1970-1-1', publish=publish) # 二、刪 book = Book.objects.last() # type: Book book.delete() Publish.objects.first().delete() # 三、改 publish = Publish.objects.last() book = Book.objects.last() # type: Book book.publish = publish book.save() publish_id = Publish.objects.last().id Book.objects.filter(name='死亡Python').update(publish_id=publish_id)
一對一關係(增刪改)
注:經過外鍵所在表決定依賴關係設計
# 一、增 detail = AuthorDetail.objects.create(age=8, telephone=13766668888, info='一個字,帥') Author.objects.create(name="Owen", author_detail=detail) Author.objects.create(name="Liuxx", author_detail_id=detail.id) # 三句一塊兒執行,兩個做者使用一條詳情,不知足惟一約束 detail = AuthorDetail.objects.create(age=88, telephone=13722222222, info='一個字,二') # Author.objects.create(name="Liuxx", author_detail_id=detail.id) # 二、刪 AuthorDetail.objects.last().delete() # 三、一對一關係不考慮連表更新
多對多關係(增刪改)
注:1.多對多關係存在關係表,關係表建議採用ManyToManyField字段處理;2.須要手動建立關係表時,在字段中明確through與through_field值。code
#Book 與 Author表都可以單獨操做,關聯關係存在於 關係表 # 問題:若是獲取關係表,經過Book的對象得到author屬性,表明關係表的對象 book = Book.objects.first() # type: Book book.author 表明關係表的對象 detail = AuthorDetail.objects.create(age=88, telephone=13744444444, info='一個字,衰') Author.objects.create(name="Egon", author_detail_id=detail.id) b1 = Book.objects.first() # type: Book b2 = Book.objects.all()[1] # type: Book a1 = Author.objects.first() # type: Author a2 = Author.objects.all()[1] # type: Author # 一、增 add() book.author.add(*authors) b1.author.add(a1.id, a2.id) b2.author.add(a1, a2) # 二、刪 # 將第二本書的關係記錄所有清除 b2.author.clear() # 經過 主鍵 或 對象 操做指定某條記錄 b1.author.remove(a1) b1.author.remove(a2.id) # 三、改 # 清除該本書的以前全部關係記錄,添加新的關係 b1.author.clear() b1.author.add(a1) # 去除新數據中不存在的值,添加新數據中新有的值,與以前重複的值保留 b2.author.set([a2.id]) a3 = Author.objects.last() b2.author.set([a2.id, a3.id])
跨表查詢
1.正向逆向概念:從存放外鍵的表到關係表稱之爲正向跨表查詢,反之稱爲逆向跨表查詢;對象
2.正向查詢經過外鍵屬性名進行跨表查詢;blog
3.逆向查詢經過關聯表對應類名小寫進行跨表查詢。ci
基於對象的跨表查詢:
在跨表查詢的規則上,跨表查詢的結果爲多條數據時須要在字段後添加_set。rem
# 一、一對多表查詢 # 需求:打印第一本書的出版社名 # book = Book.objects.first() # type: # print(book.publish.name) # 需求:第一個出版社出版過的書們的名字, # publish = Publish.objects.first() # print(publish.book_set.all()) # for book in publish.book_set.all(): # print(book.name) # 需求:打印第二本書的出版社地址 # address = Book.objects.all()[1].publish.address # print(address) # 需求:第二個出版社出版過的書們的價格 # publish = Publish.objects.all()[1] # type: Publish # for book in publish.book_set.all(): # print(book.price) # 二、一對一 # author = Author.objects.first() # type: Author # print(author.author_detail.telephone) # author_detail = AuthorDetail.objects.last() # type: AuthorDetail # print(author_detail.author.name) # 三、多對多 # 需求:第一本書的做者們的姓名 # book = Book.objects.filter(name="資治通鑑").first() # type: Book # # print(book.author) # for author in book.author.filter(name__endswith="xx"): # print(author.name) # 四、 # 需求:第二個做者寫過的書們的書名 # author = Author.objects.all()[1] # type: Author # for book in author.book_set.all(): # print(book.name) # 需求:第一個出版社出版過的書們的名字與價格 # publish = Publish.objects.first() # books = publish.book_set.all() # 數據全部字段數據都被保留存放在對象(們)中 # for book in books: # print(book.name, book.price) # books_infos = publish.book_set.values('name', 'price') # 數據指定字段數據被保留存放在列表中 # print(books_infos) # 五、多級跨表查詢 # 需求:第一個出版社出版過書們的做者們的電話號碼 # publish = Publish.objects.first() # type: Publish # books = publish.book_set.all() # for book in books: # type: Book # authors = book.author.all() # type: Author # for author in authors: # type: Author # print(author.author_detail.telephone)
基於雙下劃線的跨表查詢:
注:filter方法與values方法支持__查詢規則。
# 一、一對多 # 需求:第一本書的出版社名 # publish_name = Book.objects.filter(id=5).values('publish__name') # print(publish_name) # 需求:第一個出版社出版過的書們, # books_infos = Publish.objects.filter(id=2).values('book__name', 'book__price') # print(books_infos) # 二、一對一 # 需求: 查詢全部大於80歲做者的名字與實際年齡 # authors_infos = Author.objects.filter(author_detail__age__gt=80).values('name', 'author_detail__age') # print(authors_infos) # 多級連表查詢 # 多表關聯:查詢出版社在上海的出版過的全部書的 做者姓名、做者電話、具體出版社名 的相關信息 # infos = Publish.objects.filter(address__contains='上海').values('book__author__name', 'book__author__author_detail__telephone', 'name') # print(infos)