1. 程式人生 > 實用技巧 >Django ORM – 多表例項筆記

Django ORM – 多表例項筆記

  往Publish表裡面新增資料
Publish = models.Publish(name="明教出版社ww",city='黑木崖',email="[email protected]")
Publish.save()
return HttpResponse("<p>資料新增成功!</p>")

往authordetail表中新增資料
AuthorDetail = models.AuthorDetail(gender="0",tel='13878934322',addr="黑木崖",birthday="1996-5-20")
AuthorDetail.save()
return HttpResponse("<p>資料新增成功!</p>")

往author表裡面新增資料
Author = models.Author(name="任盈盈",age='23',au_detail_id="3")
Author.save()
return HttpResponse("<p>資料新增成功!</p>")


ORM - 新增資料
1、一對多(外來鍵 ForeignKey)
獲取出版社物件
方式一: 傳物件的形式,返回值的資料型別是物件,書籍物件。
步驟:
a. 獲取出版社物件
b. 給書籍的出版社屬性 pulish 傳出版社物件
pub_obj = models.Publish.objects.filter(pk=1).first()
print(pub_obj)
給書籍的出版社屬性publish傳出版社物件
book = models.Book.objects.create(title="菜鳥教程", price=200, pub_date="2010-10-10", publish=pub_obj)
print(book)
return HttpResponse(book)

方式二: 傳物件 id 的形式(由於傳過來的資料一般是 id,所以傳物件 id 是常用的)。
一對多中,設定外來鍵屬性的類(多的表)中,MySQL 中顯示的欄位名是:外來鍵屬性名_id。
返回值的資料型別是物件,書籍物件。
步驟:
a. 獲取出版社物件的 id
b. 給書籍的關聯出版社欄位 pulish_id 傳出版社物件的 id
獲取出版社物件
pub_obj = models.Publish.objects.filter(pk=1).first()
獲取出版社物件的id
pk = pub_obj.pk
給書籍的關聯出版社欄位 publish_id 傳出版社物件的id
book = models.Book.objects.create(title="衝靈劍法", price=100, pub_date="2010-10-10", publish_id=pk)
return HttpResponse(book)


2、多對多(ManyToManyField):在第三張關係表中新增資料
方式一: 傳物件形式,無返回值。
步驟:
a. 獲取作者物件
b. 獲取書籍物件
c. 給書籍物件的 authors 屬性用 add 方法傳作者物件
獲取作者物件
chong = models.Author.objects.filter(name="令狐沖").first()
ying = models.Author.objects.filter(name="任盈盈").first()
print(chong,ying)
獲取書籍物件
book = models.Book.objects.filter(title="衝靈劍法").first()
給書籍物件的 authors 屬性用 add 方法傳作者物件
book.authors.add(chong)
return HttpResponse(chong)


方式二: 傳物件id形式,無返回值。
步驟:
a. 獲取作者物件的 id
b. 獲取書籍物件
c. 給書籍物件的 authors 屬性用 add 方法傳作者物件的 id
chong = models.Author.objects.filter(name="令狐沖").first()
pk = chong.pk
book = models.Book.objects.filter(title="衝靈劍法").first()
book.authors.add(pk)
return HttpResponse(chong)

3、關聯管理器(物件呼叫)
前提:
多對多(雙向均有關聯管理器)
一對多(只有多的那個類的物件有關聯管理器,即反向才有)
語法格式:
正向:屬性名
反向:小寫類名加 _set
注意:一對多隻能反向
常用方法:
add():用於多對多,把指定的模型物件新增到關聯物件集(關係表)中。
注意:add() 在一對多(即外來鍵)中,只能傳物件( *QuerySet資料型別),不能傳 id(*[id表])。
方式一:傳物件
book_obj = models.Book.objects.get(id=10)
author_list = models.Author.objects.filter(id__gt=2)
book_obj.authors.add(*author_list) 將 id 大於2的作者物件新增到這本書的作者集合中

方式二:傳物件 id
book_obj.authors.add(*[1, 3]) 將 id=1 和 id=3 的作者物件新增到這本書的作者集合中
反向:小寫表名_set
ying = models.Author.objects.filter(name="任盈盈").first()
book = models.Book.objects.filter(title="衝靈劍法").first()
ying.book_set.add(book)

create():建立一個新的物件,並同時將它新增到關聯物件集之中。
返回新建立的物件。
pub = models.Publish.objects.filter(name="明教出版社").first()
wo = models.Author.objects.filter(name="任我行").first()
book = wo.book_set.create(title="吸星大法", price=300, pub_date="1999-9-19", publish=pub)
print(book, type(book))

remove():從關聯物件集中移除執行的模型物件。
對於 ForeignKey 物件,這個方法僅在 null=True(可以為空)時存在,無返回值。
author_obj = models.Author.objects.get(id=1)
book_obj = models.Book.objects.get(id=11)
author_obj.book_set.remove(book_obj)

clear():從關聯物件集中移除一切物件,刪除關聯,不會刪除物件。
對於 ForeignKey 物件,這個方法僅在 null=True(可以為空)時存在。
無返回值。
清空獨孤九劍關聯的所有作者
book = models.Book.objects.filter(title="菜鳥教程").first()
book.authors.clear()


ORM 查詢
基於物件的跨表查詢。
正向:屬性名稱
反向:小寫類名_set
一對多
查詢主鍵為 1 的書籍的出版社所在的城市(正向)。
book = models.Book.objects.filter(pk=10).first()
res = book.publish.city
print(res, type(res))

查詢明教出版社出版的書籍名(反向)。
反向:物件.小寫類名_set(pub.book_set) 可以跳轉到關聯的表(書籍表)。
pub.book_set.all():取出書籍表的所有書籍物件,在一個 QuerySet 裡,遍歷取出一個個書籍物件。
pub = models.Publish.objects.filter(name="明教出版社").first()
res = pub.book_set.all()
for i in res:
print(i.title)
return HttpResponse(res)一對一

查詢令狐沖的電話(正向)
正向:物件.屬性 (author.au_detail) 可以跳轉到關聯的表(作者詳情表)
author = models.Author.objects.filter(name="令狐沖").first()
res = author.au_detail.tel
print(res)
return HttpResponse('ok')

查詢所有住址在黑木崖的作者的姓名(反向)。
一對一的反向,用 物件.小寫類名 即可,不用加 _set。
反向:物件.小寫類名(addr.author)可以跳轉到關聯的表(作者表)。
addr = models.AuthorDetail.objects.filter(addr="黑木崖").first()
res = addr.author.name
print(res, type(res))
return HttpResponse('ok')

多對多
菜鳥教程所有作者的名字以及手機號(正向)。
正向:物件.屬性(book.authors)可以跳轉到關聯的表(作者表)。
作者表裡沒有作者電話,因此再次通過物件.屬性(i.au_detail)跳轉到關聯的表(作者詳情表)。
book = models.Book.objects.filter(title="菜鳥教程").first()
res = book.authors.all()
for i in res:
print(i.name, i.au_detail.tel)
return HttpResponse('ok')

查詢任我行出過的所有書籍的名字(反向)。
author = models.Author.objects.filter(name="任我行").first()
res = author.book_set.all()
for i in res:
print(i.title)
return HttpResponse('ok')

基於雙下劃線的跨表查詢
正向:屬性名稱__跨表的屬性名稱 反向:小寫類名__跨表的屬性名稱
一對多
查詢菜鳥出版社出版過的所有書籍的名字與價格。
res = models.Book.objects.filter(publish__name="菜鳥出版社").values_list("title", "price")
print(res)
return HttpResponse('ok')

反向:通過 小寫類名__跨表的屬性名稱(book__title,book__price) 跨表獲取資料。
res = models.Publish.objects.filter(name="菜鳥出版社").values_list("book__title", "book__price")
print(res)
return HttpResponse('ok')

多對多
查詢任我行出過的所有書籍的名字。
正向:通過 屬性名稱__跨表的屬性名稱(authors__name) 跨表獲取資料:
res = models.Book.objects.filter(authors__name="任我行").values_list("title")
return HttpResponse('ok')

反向:通過 小寫類名__跨表的屬性名稱(book__title) 跨表獲取資料:
res = models.Author.objects.filter(name="任我行").values_list("book__title")
return HttpResponse('ok')
一對一
查詢任我行的手機號。
正向:通過 屬性名稱__跨表的屬性名稱(au_detail__tel) 跨表獲取資料。
res = models.Author.objects.filter(name="任我行").values_list("au_detail__tel")
return HttpResponse('ok')
反向:通過 小寫類名__跨表的屬性名稱(author__name) 跨表獲取資料。
res = models.AuthorDetail.objects.filter(author__name="任我行").values_list("tel")
return HttpResponse('ok')