一、ORM生成關聯模型
(1) 一對一:表示和AuthorDetail這張表的nid構成關聯,一對一在人任意一張表構建關聯都可以,on_delete類似于mysql的關聯刪除
publish = models.OneToOneField(to='AuthorDetail',to_field='nid',on_delete=models.CASCADE)
(2) 一對多:表示和publish這張表的nid構成關聯,一對多要在多的那張表構建關聯
publish = models.ForeignKey(to="publish",to_field="nid",on_delete=models.CASCADE)
(3) 多對多:在一張表下(例如book)寫這段代碼,那么會自動生成一張表,表明為book_author(由book和變量author拼成),里邊有book_id,Author_id,以及2個關聯外鍵。
author = models.ManyToManyField(to='Author')
一對一和一對多都會在執行代碼的那張表里添加外鍵字段,多對多則是新生成一張表。
二、多表操作
(1)添加
1:一對多:
方式1:通過自己寫
Book.objects.create(title='小說1',price=100,publishDate='2020-9-9',publish_id=1)
方式2:通過對象傳
pub_obj = Publish.objects.filter(id=1).first() Book.objects.create(title='小說1',price=100,publishDate='2020-9-9',publish=pub_obj)
2:一對一:和一對多基本一樣
3:多對多:先生成一個book對象,然后通過add構建book和author的關聯,其自動會在book_author表中添加關聯。
book_obj=Book.objects.create(title='小說2',price=100,publishDate='2020-9-9',publish_id=2)
author1 = Author.object.get(name='author1'
author2 = Author.object.get(name='author2')
book_obj.author.add(author1,author2)#author為多對多字段變量名稱(manytomany那個)
#book_obj.author.add(1,2,3)
解除關聯:
book = Book.objects.filter(nid=4).first() book.author.remove(1,2,3) #等價于book.author.remove(*[1,2,3]) #book.author.clear() 清除所有
(2)查詢
正向查詢:從關聯屬性所在的表去查詢,用字段
反向查詢:反之,用name_set,其中name為表名
1:基于對象
一對多:
正:查詢xx的出版社
book_obj = Book.objects.filter(title='xx').first() print(book_obj.publish) print(book_obj.publish.name)
反:查詢xx出版社出版過的書籍
publish = Publish.objects.filter(name='xx').first() ret = publish.book_set.all() print(ret)
多對多:
正:查詢ss的作者名
book_obj = Book.objects.filter(title='ss').first()
author_list = book_obj.author.all()
for author in author_list:
print(author.name)
反:查詢ss出版過的書籍
ss = Author.objects.filter(name='ss').first() book_list = ss.book_set.all() for book in book_list: print(book.title)
一對一:
正:查詢作者p1的電話
p1 = Author.objects.filter(name='p1').first() print(p1.authordetail.telephone)
反:查詢電話為199的作者年齡
phone = AuthorDetail.objects.filter(phone='199').first() print(phone.author.age)
2:基于雙下劃線(join)
正向查詢:從關聯屬性所在的表去查詢,用字段
反向查詢:反之,用表名小寫,代表聯表。
一對多:
正:查詢xx的出版社名
ret = Book.objects.filter(title='xx').values('publish__name') print(ret) #返回的是queryset對象列表
反: 查詢xx的出版社名
ret = Publish.objects.filter(book__title='xx').values('name')#方法二 print(ret)
多對多:
正:查詢xx的作者名
ret = Book.objects.filter(title='xx').values('author__name') print(ret)
反:查詢xx的作者名
ret = Author.objects.filter(book_title='xx').vaules('name') print(ret)
一對一:查詢xx手機號
正:查詢xx的手機號
ret = Author.objects.filter(name='xx').vaules('authordetail_phone') print(ret)
反:查詢xx的手機號
ret = AuthorDetail.objects.filter(author__name='xx').values('phone') print(ret)
連續跨表:查詢手機號以199開頭的作者出版過的書籍以及對應出版社名
方式1:
ret = Book.objects.filter(author__authordetail__phone__startwith='119').values('title','publish__name') print(ret)
聯接了author,authordetail,book,以及publish的表。
方式2:
ret = Author.objects.filter(authordetail__phone__startwith='119').values('book__title','book__publish__name') print(ret)
3:聚合
有Max,Min,Count,Avg等函數
例子:計算所有書的平均價格
ret = Book.objects.all().aggregate(Avg('price')) print(ret)
4:分組
1:單表
例子: 查詢每一個部門的名稱以及員工的平均薪水。
from django.db.models import Avg,Max,Min,Count
ret = emp.objects.values('dep').annotate(avg_salary=Avg('salary'))
print(ret)
2:多表
from django.db.models import Avg,Max,Min,Count ret = Publish.objects.values('nid').annotate(c=Count("book__title")).vaules('name','c') print(ret)
5:F與Q
補充:ORM新增字段遷移時,要設置默認值default
F查詢主要是表內部字段之間進行gt,lt、=,對比時使用的。因為默認python是找不到數據庫的對比字段的。
from django.db.models import F,Q ret = Book.objects.filter(num1__gt=F('num2')) ret = Book.objects.all().update(price=F('price')*2)
Q查詢主要是支持與或非選項。&、|、~,默認django是與操作。
例子:找出名字不是xx,并且價格為100或200的書籍
from django.db.models import F,Q ret = Book.objects.filter(~Q(title='xx')&Q(price=100)|Q(price=200))
浙公網安備 33010602011771號