表之間的關係 一對一 xx=models.OneToOneField(to='要關聯的表名',to_field='要關聯表名的欄位',on_delete=models.CASCADE) # on_delete 刪除時的一些級聯效果,to_field可以不用寫,預設是關聯到另一張表的主鍵,on_fie ...
表之間的關係
- 一對一
xx=models.OneToOneField(to='要關聯的表名',to_field='要關聯表名的欄位',on_delete=models.CASCADE) # on_delete 刪除時的一些級聯效果,to_field可以不用寫,預設是關聯到另一張表的主鍵,on_field在1.x版本的Django中不用寫,預設是級聯刪除的,2.x的版本中必須要寫
- 一對多
xx=models.foreignKey(to='要關聯的表名',to_field='要關聯表名的欄位',on_delete=models.CASCADE)
- 多對多
xx = models.ManyToManyField(to='另外一個表名') #這是自動創建的第三表
建表準備
- 建立四張表: 作者表 -- 作者信息表 -- 出版社表 -- 書籍表
- 表之間的對應關係如下
- 一個作者應該對應一個相應的作者信息,所以作者表與作者信息表的關係為一對一 : oneToOnefield
- 一個出版社可以出版很多書,一本書也可以有多個出版社出版,為多對多,但是在這裡將此設置為一個出版社出很對書,一對多的關係: foreignkey
- 作者和書籍的關係為多對多: ManyToManyField
# 作者表 class Author(models.Model): name=models.CharField( max_length=32) age=models.IntegerField() #authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE) authorDetail=models.OneToOneField(to='AuthorDetail') #一對一到AuthorDetail表 生成為表欄位之後,會自動變為authorDetail_id這樣的一個名稱 def __str__(self): return self.name # 作者詳細信息表 class AuthorDetail(models.Model): birthday=models.DateField() telephone=models.CharField(max_length=32) addr=models.CharField( max_length=64) def __str__(self): return self.addr # 出版社表和書籍表 是 一對多的關係 class Publish(models.Model): name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() def __str__(self): return self.name # 書籍表 class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) # 整數位5位,小數位2位 publishs=models.ForeignKey(to="Publish") authors=models.ManyToManyField(to='Author',) # 註意不管是一對多還是多對多,寫to這個參數的時候,最後後面的值是個字元串,不然你就需要將你要關聯的那個表放到這個表的上面 def __str__(self): return self.titleView Code
增加數據
- 一對一增加(先給作者詳細信息表中增加數據,再增加作者表的數據)
new_author_detail = models.AuthorDetail.objects.create( birthday='1979-08-08', telephone='138383838', addr='北京', ) obj = models.AuthorDetail.objects.filter(addr='山西').first() #方式1 models.Author.objects.create( name='張三', age='40', authorDetail=new_author_detail, ) # 方式2 常用 models.Author.objects.create( name='張三', age='40', authorDetail_id=obj.id, )
- 一對多增加
# 方式1 models.Book.objects.create( title = '追風箏的人', publishDate='2019-07-22', price=25, publishs=models.Publish.objects.get(id=1), ) # 方式2 常用 obj = models.Publish.objects.get(id=1) models.Book.objects.create( title='追風箏的人', publishDate='2019-07-21', price=25, publishs_id=obj.id )
- 多對多增加
# 方式1 常用 book_obj = models.Book.objects.get(id=1) # 拿到book的id book_obj.authors.add(*[1,2]) # 插入作者的id 打散的形式插入 # 方式2 author1 = models.Author.objects.get(id=1) author2 = models.Author.objects.get(id=3) book_obj = models.Book.objects.get(nid=5) book_obj.authors.add(*[author1,author2])
刪除數據
一對一和一對多的刪除和單表刪除是一樣的 # 一對一 表一外鍵關聯到表二,表一刪除,不影響表2,表2刪除會影響表1 # 作者表外鍵關聯作者詳細信息表 models.AuthorDetail.objects.get(id=2).delete() # 作者表會受影響 models.Author.objects.get(id=3).delete() # 作者詳細信息表不會影響 # 一對多 # 書籍表外鍵關聯出版社表 models.Publish.objects.get(id=1).delete() # 書籍表會影響 models.Book.objects.get(id=1).delete() # 出版社表不會影響 # 多對多關係刪除 book_obj = models.Book.objects.get(nid=6) book_obj.authors.remove(6) # 刪除書id為6和作者id為6的一行數據 book_obj.authors.remove(*[5,6]) book_obj.authors.clear() # 清空表中所有數據 book_obj.authors.set('1') #刪除然後更新,後面寫字元串 book_obj.authors.set(['5','6'])
更新數據
# 一對一 models.Author.objects.filter(id=5).update( name='張三', age=16, authorDetail=models.AuthorDetail.objects.get(id=5), authorDetail_id=4, ) #一對多 models.Book.objects.filter(pk=4).update( # pk=4等價於id=4 title='白夜行', publishs=models.Publish.objects.get(id=3), publishs_id=3, ) #一對多 models.Publish.objects.filter(pk=2).update( id=4, # 沒有級聯更新,報錯!! )
基於對象的跨表查詢
- 類似於子查詢
- 正向查詢和反向查詢: 關係屬性(欄位)寫在哪個類(表)裡面,從當前類(表)的數據去查詢它關聯類(表)的數據叫做正向查詢,反之叫做反向查詢
############## 一對一 查詢Alex的電話號碼(正向查詢) obj = models.Author.objects.get(name='alex') print(obj.authorDetail.telephone) 反向查詢: 查詢333這個號碼是誰的 #obj = models.AuthorDetail.objects.filter(telephone='333').first().author.name obj = models.AuthorDetail.objects.get(telephone='333').author.name print(obj) ''' 正向查詢: Authorobj.authorDetail,對象.關聯屬性名稱 Author -----------------------------------> AuthorDetail <----------------------------------- 反向查詢: AuthorDetailobj.author ,對象.小寫類名 ''' ######### 一對多 查詢追風箏的人是哪個出版社出版的(正向查詢) obj = models.Book.objects.get(title='追風箏的人') print(obj.publishs.name,obj.publishs.city) 查看新華出版社出了什麼書(反向查詢) obj = models.Publish.objects.get(name='人民出版社') for i in obj.book_set.all(): # 迴圈拿到具體的值 print(i) ''' 正向查詢 book_obj.publishs 對象.屬性 Book ---------------------------------------------> Publish <---------------------------------------------- 反向查詢 publish_obj.book_set.all() 對象.表名小寫_set ''' ########## 多對多 查看狼道這本書是誰寫的(正向查詢) obj = models.Book.objects.get(title='狼道') for i in obj.authors.all(): print(i) 查詢張三寫過什麼書(反向查詢) obj = models.Author.objects.get(name='張三') for i in obj.book_set.all(): print(i) ''' 正向查詢 book_obj.authors.all() 對象.屬性 Book ---------------------------------------------> Author <---------------------------------------------- 反向查詢 author_obj.book_set.all() 對象.表名小寫_set '''View Code
基於雙下劃線的跨表查詢
- 類似於連表查詢
-
########### 一對一 查詢lisi的電話號碼(正向查詢) obj=models.Author.objects.filter(name='lisi') print(obj.values('authorDetail__telephone')[0]['authorDetail__telephone']) obj = models.AuthorDetail.objects.filter(author__name='lisi').values('telephone') print(obj) 查詢333電話是誰的 obj = models.AuthorDetail.objects.filter(telephone='333') print(obj.values('author__name')) obj = models.Author.objects.filter(authorDetail__telephone='333').values('name') print(obj) ################# 一對多 查詢狼道是那個出版社出版的 obj = models.Book.objects.filter(title='狼道').values('publishs__name') print(obj) obj = models.Publish.objects.filter(book__title='狼道').values('name') print(obj) 查詢新華出版社出版了什麼書 obj = models.Publish.objects.filter(name='新華出版社').values('book__title') print(obj) obj = models.Book.objects.filter(publishs__name='新華出版社').values('title') print(obj) ################ 多對多 解憂雜貨店這本書是誰寫的 obj = models.Book.objects.filter(title='解憂雜貨店').values('authors__name') print(obj) obj = models.Author.objects.filter(book__title='解憂雜貨店').values('name') print(obj) alex寫了什麼書 obj= models.Author.objects.filter(name='alex').values('book__title') # print(obj) obj = models.Book.objects.filter(authors__name='alex').values('title') print(obj) ############### 進階的 玄機出版社 出版的書名稱及作者的名稱 obj = models.Publish.objects.filter(name='玄機出版 社').values('book__title','book__authors__name') print(obj) obj = models.Book.objects.filter(publishs__name='玄機出版社').values('title','authors__name') print(obj) obj = models.Author.objects.filter(book__publishs__name='玄機出版社').values('name','book__title') print(obj)
View Code