一.建立表
1.一對多
必須在"多"的表中建立關聯字段,在外加約束
class Book(models.Model):
id=models.AotuField(primary_key=True)
title=models.CharField(max_length=32)
publish=models.ForeignKey(to='Publish',on_delete=models.CASCADE)
注:正常爲字段起名便可,Django會默認爲外鍵屬性拼接_id,以此做爲表的字段
to對應的是關聯的表
2.一對一
能夠在任意表中建立關鍵字段,Django默認爲其加上惟一約束
class Author(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
ad=models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)
3.多對多
class Book(models.Model):
id=models.AotuField(primary_key=True)
title=models.CharField(max_length=32)
authors=models.ManyToMany(to='Author')
注:Django對默認爲其建立第三張表
第三張表的表名爲:此表表名(小寫)_建立多對多的字段
第三張表的字段爲 id,此表表名_id,關聯表表名_id
注:用Django建立表時,不加id字段會被默認添加
外鍵字段有一個null=True的設置,表示容許外鍵爲空值
二.對錶記錄的操做
1.填加表記錄
(1)一對多
方式1:
Book.objects.create(title='王八蛋啥時候來',pub_date='2012-12-12',price=12,publish_id=1)
此處的1表明'一'表中的主鍵值爲1
方式2:
publish_obj=publish.objects.get(id=1)
Book.objects.create(title='王八蛋啥時候來',pub_date='2012-12-12',price=12,publish=publish_obj)
注:若是直接用數字,要用表的字段值 publish_id
若是用'一'表對象,要用類的屬性 publish
(2)多對多
a.生成書籍對象
book_obj=Book.objects.create(title='王八蛋啥時候來',pub_date='2012-12-12',price=12,publish_id=1)
b.爲書籍對象綁定做者
shy=Author.objects.filter(name='shy').first()
jwb=Author.objects.filter(name='jwb').first()
c.向關係表book_authors中添加紀錄
方式1:book_obj.authors.add(shy,jwb)
方式2:book_obj.authors.add(1,2)
方式3:book_obj.authors.add(*[1,2])
其餘方法:
book_obj.authors.remove() # 將某個特定的對象從被關聯對象集合中去除。 (book_obj.authors.remove(*[]))
book_obj.authors.clear() #清空被關聯對象集合
book_obj.authors.set() #先清空再設置
2.查詢表記錄
注:正向查詢與反向查詢
正向查詢:關聯屬性所在的表查詢關聯表記錄
反向查詢:關聯表查詢關聯屬性所在的表記錄
(1)基於對象的跨表查詢
一對多
正向查詢按字段:book.publish
Book----------------------------------------->Publish
反向查詢按表名小寫+_set.all():publish.book_set.all()
正向查詢例:查詢python這本書出版社的名字和郵箱
book_obj=Book.objects.filter(title='python').first()
publish_obj=Publish.objects.filter(id=book_obj.publish).first().values('name','email')
反向查詢例:查詢人民出版社出版的全部書籍的名稱
publish_obj=Publish.objects.filter(name='人民出版社').first()
print(publish_obj.book_set.all())
多對多
正向查詢按字段:book.authors.all()
Book----------------------------------------->Publish
反向查詢按表名小寫+_set.all():author.book_set.all()
正向查詢例:查詢python這本書做者的名字
book_obj=Book.objects.filter(title='python').first()
print(book_obj.authors.all().values('name'))
反向查詢例:查詢shy出版過的全部書籍的名稱
author_obj=Author.objects.filter(name='shy').first()
print(author_obj.book_set.all().values('title'))
一對一
正向查詢按字段:author.ad
Book---------------------------------------->Publish
反向查詢按表名小寫:authordetail.author
正向查詢例:查詢shy的手機號
author_obj=Author.objects.filter(name='shy').first()
print(author_obj.ad.tel)
反向查詢例:查詢地址爲北京的做者
authordetail_obj=AuthorDetail.objects.filter(addr='北京')
print(authordetail_obj.author)
(2)基於雙下劃線的跨表查詢
基於雙下劃線的單次跨表查詢
語法:正向查詢按字段,反向查詢按表名小寫
一對多查詢
正向查詢例:查詢本草綱目這本書出版社的名字
Book.objects.filter(title='本草綱目').values('publish__name')
正向查詢例:查詢北京出版社出版的全部書籍的名稱與價格
Publish.objects.filter(name='北京出版社').values('book__title','book__price')
多對多查詢
正向查詢例:查詢皇帝的新裝這本書的做者和年齡
Book.objects.filter(title='皇帝的新裝').values('authors__age')
反向查詢例:查詢尚宏運出版過的全部書籍的名字
Author.objects.filter(name='尚宏運').values('book__title')
一對一查詢
正向查詢例:查詢尚宏運的手機號
Author.objects.filter(name='尚宏運').values('ad__tel')
反向查詢例:查詢手機號爲123456的做者
AuthorDetail.objects.filter(author__name='尚宏運').values('tel')
基於雙下劃線的連續跨表查詢:
例查詢北京出版社出版過的全部書籍的名字及做者的名字
方式1:
Publish.objects.filter(name='北京出版社').values('book__title','book__authors__name')
方式2;
Book.objects.filter(publish__name='北京出版社').values('title','authors__name')
方式3:
Author.objects.filter(book__publish__name='北京出版社').values('book__title','name')
(3)聚合和分組查詢
聚合:
注:使用聚合函數前先引入
from django.db.models import Avg,Max,Sum,Min,Count
例:查詢全部書籍的平均價格
Book.objects.all().aggregate(avg_price=Avg('price'))
分組:
語法:annotate()前values哪一個字段,就用哪一個字段進行分組,在annotate後的括號中使用聚合函數
單表分組查詢
例:查詢每個部門對應員工的平均薪水
Emp.obj.values('dep').annotate(Avg('salary'))
跨表分組查詢
例:查詢每個出版社的名稱以及出版的書的平均價格
Publish.objects.values('name').annotate(Avg('book__price'))
簡便寫法:
例:查詢每個出版社的名稱,以及對應書籍的平均價格
方式1:
Publish.objects.values('name').annotate(avg_price=Avg('book__price'))
方式2:
Publish.objects.all().annotate(avg_price=Avg('book__price')).values('name','avg_price')
方式3:
Publish.objects.annotate(avg_price=Avg('book__price')).values('name','avg_price')
注:使用聚合函數時,最好另起別名
(4)F與Q查詢 注:使用F和Q查詢前須要先引入 from django.db.models import F,Q F查詢 例:查詢評論數大於點贊數的全部書籍的名稱 Book.objects.filter(comment_count__gt=F('poll_count')).values('title') 給每一本書的價格提高100 Book.objects.all().values(price=F('price')+100) Q查詢 當查詢的條件中存在與(&)或(|)非(~)時,使用Q查詢 例:查詢價格大於300或評論數大於3000的書籍 Book.objects.filter(Q(price__gt=300)|Q(comment__count__gt=3000)) 查詢價格大於100,或者不是尚宏運寫的書 Book.objects.filter(Q(price__gt=100)|~Q(authors__name='尚宏運')).values('title')