Django模型層之多表操作
阿新 • • 發佈:2018-11-13
一、建立多表模型
例項:
作者表:
擁有欄位:姓名(name),性別(sex),該表與書籍表之間為多對多的關係
作者詳情表:
擁有欄位:地址(addr),手機號(phone),該表與作者表之間為一對一的關係
出版社表:
擁有欄位:名字(name),地址(addr),該表與書籍表之間為一對多的關係
書籍表:
擁有欄位:書名(name),單價(price)
分析:一本書可以擁有多個作者,一個作者可以寫多本書,所有作者與書籍之間為多對多的關聯關係(Many-To-Many);一本書只有一個出版社,但是一個出版社可以出版多種書籍,所以出版社和書籍之間是一對多的關聯關係(One-To-Many);作者與作者詳情就是一對一關聯關係(One-To-One)
在models.py下建立模型如下:
class Publish(models.Model): name = models.CharField(max_length=255) addr = models.CharField(max_length=255) def __str__(self): return self.name class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=255) sex= models.IntegerField() authordetail = models.OneToOneField(to='AuthorDetail') def __str__(self): return self.name class AuthorDetail(models.Model): id = models.AutoField(primary_key=True) addr = models.CharField(max_length=255) phone = models.CharField(max_length=255)class Book(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=255) price = models.DecimalField(max_digits=5, decimal_places=2) # 外來鍵,關聯關係寫在一對多中多的那一方 publish = models.ForeignKey(to=Publish) authors = models.ManyToManyField(to=Author) def __str__(self): return self.name
注意事項;
1.id欄位不寫的話會自動新增 2.對於外來鍵欄位,Django會在欄位名上新增"_id"來建立資料庫中的列名 3.外來鍵欄位ForeignKey有一個null=True的設定,你可以賦給它空值None
二、新增表記錄
一對一:
# 方式一: detail_obj = models.AuthorDetail.objects.filter(id=2).first() models.Author.objects.create(name='Yven',sex=1,authordetail=detail_obj) # 方式二: models.Author.objects.create(name='hwt',sex=2,authordetail_id=1)
一對多:
# 方式一: publish_obj = models.Publish.objects.filter(id=2).first() models.Book.objects.create(name='水滸傳',price=24.5,publish=publish_obj) # 方式二: models.Book.objects.create(name='西遊記',price=24.5,publish_id=2)
多對多:
# 獲得書籍物件 book = models.Book.objects.create(name='水滸傳',price=24.5,publish_id=3) # 獲得作者物件 yven = models.Author.objects.get(name='Yven') hwt = models.Author.objects.get(name='hwt') # 繫結多對多關係 # add中可以傳遞物件,可以傳遞id,也可以傳遞*列表如:(*[yven,hwt]) book.authors.add(yven,hwt) #多對多關係其他常用API: # 將某個特定的物件從被關聯物件集合中去除,可以傳遞物件,可以傳遞id,也可以傳遞*列表如:(*[yven,hwt]) book.authors.remove() # 清空被關聯物件集合,無需傳參 book.authors.clear() # 先清空再設定,傳遞的引數必須是可迭代物件,一般為列表,列表內可以是物件,也可以是id book.authors.set()
三、基於物件的跨表查詢
一對一:
#正向:關聯欄位在哪裡,從哪裡開始就是正向。正向查詢按欄位 #查詢小明作者的手機號 author = models.Author.objects.filter(name='小明').first() authordetail = author.authordetail#authordetail是欄位名 print(authordetail.phone) #反向:反向查詢按表名小寫 #查詢地址是北京的作者名字 authordetail = models.AuthorDetail.objects.filter(addr='北京').first() author = authordetail.author#author是表名 print(author.name)
一對多:
#正向:正向查詢按欄位 # 查詢紅樓夢這本書的出版社郵箱 book = models.Book.objects.filter(name='紅樓夢').first() publish = book.publish print(publish.email) #反向:反向按表名小寫_set.all() # 查詢地址是北京 的出版社出版的圖書 publish = models.Publish.objects.filter(addr='北京').first() book = publish.book_set.all() print(book)
多對多:
#正向:正向查詢按欄位.all() #查詢紅樓夢這本書所有的作者 book = models.Book.objects.filter(name='紅樓夢').first() author = book.authors.all() print(author) #反向查詢:反向按表名小寫_set.all() #查詢小明寫的所有書 author = models.Author.objects.filter(name='小明').first() book = author.book_set.all() print(book)
注:基於物件的查詢,其本質就是多次查詢(子查詢)
四、基於雙下劃線的跨表查詢
Django還提供了一種直觀而搞笑的方式在查詢(lookups)種表示關聯關係,它能自動確認SQL JOIN聯絡。要做跨關係查詢,就使用兩個下劃線來連線模型(model)間關聯欄位的名稱,知道最終連結到你想要的model為止。
一對一查詢:
正向查詢(按欄位):authordetail # 查詢Yven的地址 models.Author.objects.filter(name='Yven').values('authordetail__addr') 反向查詢(按表名):author # 查詢Yven的地址 models.AuthorDetail.objects.filter(author__name='Yven').values('addr')
一對多查詢:
正向查詢(按欄位):publish # 查詢西遊記的出版社名 models.Book.objects.filter(name='西遊記').values('publish__name') 反向查詢(按表名):book # 查詢西遊記的出版社名 models.Publish.objects.filter(book__name='西遊記').values('name')
多對多查詢:
正向查詢(按欄位):authors # 查詢水滸傳的作者性別 models.Book.objects.filter(name='水滸傳').values('authors__sex') 反向查詢(按表名):book # 查詢水滸傳的作者性別 models.Author.objects.filter(book__name='水滸傳').values('sex')