久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Django ORM – 多表實例

 rongq2007 2021-07-16

Django教程

Django ORM - 單表實例

Django ORM – 多表實例https://www.runoob.com/django/django-orm-2.html

Django ORM – 多表實例

表與表之間的關(guān)系可分為以下三種:

  • 一對一: 一個人對應(yīng)一個身份證號碼,數(shù)據(jù)字段設(shè)置 unique,。

  • 一對多: 一個家庭有多個人,,一般通過外鍵來實現(xiàn)。

  • 多對多: 一個學生有多門課程,,一個課程有很多學生,,一般通過第三個表來實現(xiàn)關(guān)聯(lián)。

創(chuàng)建模型

接下來我們來看下多表多實例,。

實例

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publish = models.ForeignKey("Publish", on_delete=models.CASCADE)
    authors = models.ManyToManyField("Author")


class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=64)
    email = models.EmailField()


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.SmallIntegerField()
    au_detail = models.OneToOneField("AuthorDetail", on_delete=models.CASCADE)


class AuthorDetail(models.Model):
    gender_choices = (
        (0, "女"),
        (1, "男"),
        (2, "保密"),
    )
    gender = models.SmallIntegerField(choices=gender_choices)
    tel = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)
    birthday = models.DateField()

說明:

  • 1,、EmailField 數(shù)據(jù)類型是郵箱格式,底層繼承 CharField,,進行了封裝,相當于 MySQL 中的 varchar,。

  • 2,、Django1.1 版本不需要聯(lián)級刪除:on_delete=models.CASCADE,Django2.2 需要,。

  • 3,、一般不需要設(shè)置聯(lián)級更新.

  • 4、外鍵在一對多的多中設(shè)置:models.ForeignKey("關(guān)聯(lián)類名", on_delete=models.CASCADE),。

  • 5,、OneToOneField = ForeignKey(...,unique=True)設(shè)置一對一,。

  • 6,、若有模型類存在外鍵,創(chuàng)建數(shù)據(jù)時,,要先創(chuàng)建外鍵關(guān)聯(lián)的模型類的數(shù)據(jù),,不然創(chuàng)建包含外鍵的模型類的數(shù)據(jù)時,外鍵的關(guān)聯(lián)模型類的數(shù)據(jù)會找不到,。

表結(jié)構(gòu)

書籍表 Book:title ,、 price 、 pub_date ,、 publish(外鍵,,多對一) 、 authors(多對多)

出版社表 Publish:name ,、 city ,、 email

作者表 Author:name 、 age ,、 au_detail(一對一)

作者詳情表 AuthorDetail:gender ,、 tel ,、 addr 、 birthday

以下是表格關(guān)聯(lián)說明:

插入數(shù)據(jù)

我們在 MySQL 中執(zhí)行以下 SQL 插入操作:

insert into app01_publish(name,city,email) values ("華山出版社", "華山", "[email protected]"), ("明教出版社", "黑木崖", "[email protected]")
 # 先插入 authordetail 表中多數(shù)據(jù)insert into app01_authordetail(gender,tel,addr,birthday) values (1,13432335433,"華山","1994-5-23"), (1,13943454554,"黑木崖","1961-8-13"), (0,13878934322,"黑木崖","1996-5-20") # 再將數(shù)據(jù)插入 author,,這樣 author 才能找到 authordetail insert into app01_author(name,age,au_detail_id) values ("令狐沖",25,1), ("任我行",58,2), ("任盈盈",23,3)


ORM - 添加數(shù)據(jù)

一對多(外鍵 ForeignKey)

方式一: 傳對象的形式,,返回值的數(shù)據(jù)類型是對象,書籍對象,。

步驟:

  • a. 獲取出版社對象

  • b. 給書籍的出版社屬性 pulish 傳出版社對象

app01/views.py 文件代碼:

def add_book(request):
    #  獲取出版社對象
    pub_obj = models.Publish.objects.filter(pk=1).first()
    #  給書籍的出版社屬性publish傳出版社對象
    book = models.Book.objects.create(title="菜鳥教程", price=200, pub_date="2010-10-10", publish=pub_obj)
    print(book, type(book))
    return HttpResponse(book)

方式二: 傳對象 id 的形式(由于傳過來的數(shù)據(jù)一般是 id,所以傳對象 id 是常用的),。

一對多中,設(shè)置外鍵屬性的類(多的表)中,,MySQL 中顯示的字段名是:外鍵屬性名_id,。

返回值的數(shù)據(jù)類型是對象,書籍對象,。

步驟:

  • a. 獲取出版社對象的 id

  • b. 給書籍的關(guān)聯(lián)出版社字段 pulish_id 傳出版社對象的 id

app01/views.py 文件代碼:

def add_book(request):
    #  獲取出版社對象
    pub_obj = models.Publish.objects.filter(pk=1).first()
    #  獲取出版社對象的id
    pk = pub_obj.pk
    #  給書籍的關(guān)聯(lián)出版社字段 publish_id 傳出版社對象的id
    book = models.Book.objects.create(title="沖靈劍法", price=100, pub_date="2004-04-04", publish_id=pk)
    print(book, type(book))
    return HttpResponse(book)

多對多(ManyToManyField):在第三張關(guān)系表中新增數(shù)據(jù)

方式一: 傳對象形式,,無返回值。

步驟:

  • a. 獲取作者對象

  • b. 獲取書籍對象

  • c. 給書籍對象的 authors 屬性用 add 方法傳作者對象

app01/views.py 文件代碼:

def add_book(request):
    #  獲取作者對象
    chong = models.Author.objects.filter(name="令狐沖").first()
    ying = models.Author.objects.filter(name="任盈盈").first()
    #  獲取書籍對象
    book = models.Book.objects.filter(title="菜鳥教程").first()
    #  給書籍對象的 authors 屬性用 add 方法傳作者對象
    book.authors.add(chong, ying)
    return HttpResponse(book)

方式二: 傳對象id形式,,無返回值,。

步驟:

  • a. 獲取作者對象的 id

  • b. 獲取書籍對象

  • c. 給書籍對象的 authors 屬性用 add 方法傳作者對象的 id

app01/views.py 文件代碼:

def add_book(request):
    #  獲取作者對象
    chong = models.Author.objects.filter(name="令狐沖").first()
    #  獲取作者對象的id
    pk = chong.pk
    #  獲取書籍對象
    book = models.Book.objects.filter(title="沖靈劍法").first()
    #  給書籍對象的 authors 屬性用 add 方法傳作者對象的id
    book.authors.add(pk)

關(guān)聯(lián)管理器(對象調(diào)用)

前提:

  • 多對多(雙向均有關(guān)聯(lián)管理器)

  • 一對多(只有多的那個類的對象有關(guān)聯(lián)管理器,即反向才有)

語法格式:

正向:屬性名反向:小寫類名加 _set

注意:一對多只能反向

常用方法:

add():用于多對多,,把指定的模型對象添加到關(guān)聯(lián)對象集(關(guān)系表)中,。

注意:add() 在一對多(即外鍵)中,只能傳對象( *QuerySet數(shù)據(jù)類型),,不能傳 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 的作者對象添加到這本書的作者集合中
return HttpResponse("ok")

反向:小寫表名_set

ying = models.Author.objects.filter(name="任盈盈").first()
book = models.Book.objects.filter(title="沖靈劍法").first()
ying.book_set.add(book)
return HttpResponse("ok")

create():創(chuàng)建一個新的對象,并同時將它添加到關(guān)聯(lián)對象集之中,。

返回新創(chuàng)建的對象,。

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))
return HttpResponse("ok")

remove():從關(guān)聯(lián)對象集中移除執(zhí)行的模型對象。

對于 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)
return HttpResponse("ok")

clear():從關(guān)聯(lián)對象集中移除一切對象,,刪除關(guān)聯(lián),,不會刪除對象。

對于 ForeignKey 對象,,這個方法僅在 null=True(可以為空)時存在,。

無返回值。

#  清空獨孤九劍關(guān)聯(lián)的所有作者
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))
return HttpResponse("ok")

查詢明教出版社出版的書籍名(反向)。

反向:對象.小寫類名_set(pub.book_set) 可以跳轉(zhuǎn)到關(guān)聯(lián)的表(書籍表)。

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("ok")

一對一

查詢令狐沖的電話(正向)

正向:對象.屬性 (author.au_detail) 可以跳轉(zhuǎn)到關(guān)聯(lián)的表(作者詳情表)

實例

author = models.Author.objects.filter(name="令狐沖").first()
res = author.au_detail.tel
print(res, type(res))
return HttpResponse("ok")

查詢所有住址在黑木崖的作者的姓名(反向),。

一對一的反向,,用 對象.小寫類名 即可,不用加 _set,。

反向:對象.小寫類名(addr.author)可以跳轉(zhuǎn)到關(guān)聯(lián)的表(作者表),。

實例

addr = models.AuthorDetail.objects.filter(addr="黑木崖").first()
res = addr.author.name
print(res, type(res))
return HttpResponse("ok")

多對多

菜鳥教程所有作者的名字以及手機號(正向)。

正向:對象.屬性(book.authors)可以跳轉(zhuǎn)到關(guān)聯(lián)的表(作者表),。

作者表里沒有作者電話,,因此再次通過對象.屬性(i.au_detail)跳轉(zhuǎn)到關(guān)聯(lián)的表(作者詳情表)。

實例

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")

查詢?nèi)挝倚谐鲞^的所有書籍的名字(反向),。

實例

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")

反向:通過 小寫類名__跨表的屬性名稱(book__title,book__price) 跨表獲取數(shù)據(jù),。

實例

res = models.Publish.objects.filter(name="菜鳥出版社").values_list("book__title","book__price")
return HttpResponse("ok")

多對多

查詢?nèi)挝倚谐鲞^的所有書籍的名字,。

正向:通過 屬性名稱__跨表的屬性名稱(authors__name) 跨表獲取數(shù)據(jù):

res = models.Book.objects.filter(authors__name="任我行").values_list("title")

反向:通過 小寫類名__跨表的屬性名稱(book__title) 跨表獲取數(shù)據(jù):

res = models.Author.objects.filter(name="任我行").values_list("book__title")

一對一

查詢?nèi)挝倚械氖謾C號,。

正向:通過 屬性名稱__跨表的屬性名稱(au_detail__tel) 跨表獲取數(shù)據(jù),。

res = models.Author.objects.filter(name="任我行").values_list("au_detail__tel")

反向:通過 小寫類名__跨表的屬性名稱(author__name) 跨表獲取數(shù)據(jù),。

res = models.AuthorDetail.objects.filter(author__name="任我行").values_list("tel")

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多