Django(part32)--一对一映射
學(xué)習筆記,僅供參考
文章目錄
- 數(shù)據(jù)表關(guān)聯(lián)關(guān)系映射
- 一對一映射
- 語法
- 創(chuàng)建一對一的數(shù)據(jù)記錄
- 查詢
- 作用
- 舉個例子
數(shù)據(jù)表關(guān)聯(lián)關(guān)系映射
在關(guān)系型數(shù)據(jù)庫中,通常不會把所有數(shù)據(jù)都放在同一張表中,這樣做會額外占用內(nèi)存空間,這時,我們會使用表關(guān)聯(lián)對各個數(shù)據(jù)表進行聯(lián)結(jié)。
-
常用的表關(guān)聯(lián)方式有三種:
-
一對一映射(如: 一個身份證對應(yīng)一個人)
-
一對多映射(如: 一個班級可以有多個學(xué)生)
-
多對多映射(如: 一個學(xué)生可以報多個課程,一個課程可以有多個學(xué)生學(xué)習)
-
一對一映射
一對一是表示事物之間存在的一對一的對應(yīng)關(guān)系。
語法
#主類 class A(model.Model):...#從屬類 class B(model.Model):屬性 = models.OneToOneField(A)
- 例子(作家和作家伴侶類)
創(chuàng)建一對一的數(shù)據(jù)記錄
from bookstore import models author1 = models.Author.objects.create(name='黃永祥') partner1 = models.Partner.objects.create(name='黃夫人', author=author1) #關(guān)聯(lián)黃永祥作家 author2 = models.Author.objects.create(name='王軍') # 一對一關(guān)系中,主類對象可以沒有對應(yīng)的從屬類對象
查詢
在Partner對象中,通過author屬性找到對應(yīng)的author對象;
在Author對象中,通過 partner屬性找到對應(yīng)的partner對象.
- 正向查詢
直接通過關(guān)聯(lián)屬性查詢即可:
# 通過partner找author from bookstore import models partner = models.Partner.objects.get(name='黃夫人') print(partner.name, '的伴侶是', partner.author.name)- 反向查詢
反向查詢?yōu)橥ㄟ^反向引用屬性查詢,反向引用屬性為實例對象.引用類名(引用類名要小寫),如作家的反向引用為作家對象.partner,需要注意的是,當反向引用不存在時,則會觸發(fā)異常
#author可以通過author.partner查找partner,如果沒有對應(yīng)的partner則觸發(fā)異常 author1 = models.Author.objects.get(name='黃永祥') print(author1.name, '的伴侶是', author1.partner.name) author2 = models.Author.objects.get(name='王軍') try:print(author2.name, '的伴侶是', author2.partner.name) except:print(author2.name, '還沒有伴侶')作用
一對一映射主要是解決數(shù)據(jù)的存儲問題,把經(jīng)常加載的一個數(shù)據(jù)放在主表中,不常用數(shù)據(jù)放在另一個副表中,這樣,在訪問主表數(shù)據(jù)時就不需要加載副表中的數(shù)據(jù),以提高訪問速度和節(jié)省內(nèi)存空間,如經(jīng)常把書的內(nèi)容和書名建成兩張表,因為在網(wǎng)站上經(jīng)常訪問書名等信息,但不需要得到書的內(nèi)容。
舉個例子
首先,我們在models.py中創(chuàng)建一個Partner模型類,并作為Author類的從屬類,形成一對一關(guān)系:
class Partner(models.Model):'''作家伴侶模型類'''name = models.CharField("姓名", max_length=50)age = models.IntegerField("年齡", null = False,default = 1)author = models.OneToOneField(Author, on_delete = models.CASCADE)記得做一下遷移:
F:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py makemigrations Migrations for 'bookstore':bookstore\migrations\0006_auto_20200621_2334.py- Alter field age on author- Create model PartnerF:\MyStudio\PythonStudio\goatbishop.project01\Django\mywebsite_db>python manage.py migrate Operations to perform:Apply all migrations: admin, auth, bookstore, contenttypes, sessions Running migrations:Applying bookstore.0006_auto_20200621_2334... OK需要注意的是,如果我們在OneToOneField中沒有加參數(shù)on_delete=models.CASCADE,則在使用python manage.py makeigrations 進行遷移時就會報錯。如果我們加入這個參數(shù),則在刪除主表的數(shù)據(jù)時,從表中的數(shù)據(jù)也會隨之刪除。
現(xiàn)在,打開Django shell創(chuàng)建記錄:
from bookstore import models author1 = models.Author.objects.create(name='黃永祥', age = 40, email="yxhuang@163.com") partner1 = models.Partner.objects.create(name='黃夫人', age = 39, author=author1) #關(guān)聯(lián)黃永祥作家 author2 = models.Author.objects.create(name='王軍', age = 36, email="wangjun@163.com")再查看一下mywebdb數(shù)據(jù)庫中 bookstore_partner表和bookstore_author表:
mysql> select * from bookstore_author; +----+--------+-----+----------------------+ | id | name | age | email | +----+--------+-----+----------------------+ | 1 | 山羊 | 20 | goatbishop@gamil.com | | 2 | 小黃 | 11 | 1033794241@qq.com | | 5 | 小黑 | 13 | xiaohei@gmail.com | | 6 | 小白 | 19 | xiaobai@gmail.com | | 7 | 山羊哥 | 28 | biggoat@gmail.com | | 8 | 黃永祥 | 40 | yxhuang@163.com | | 9 | 王軍 | 36 | wangjun@163.com | +----+--------+-----+----------------------+ 7 rows in set (0.00 sec)mysql> select * from bookstore_partner; +----+--------+-----+-----------+ | id | name | age | author_id | +----+--------+-----+-----------+ | 1 | 黃夫人 | 39 | 8 | +----+--------+-----+-----------+ 1 row in set (0.00 sec)我們看到bookstore_partner表中黃夫人的author_id字段值為8,它對應(yīng)著bookstore_author表中的id值8
我們再做一些查詢工作:
#正向 partner = models.Partner.objects.get(name='黃夫人') print(partner.name, '的伴侶是', partner.author.name) #反向 author1 = models.Author.objects.get(name='黃永祥') print(author1.name, '的伴侶是', author1.partner.name) author2 = models.Author.objects.get(name='王軍') try:print(author2.name, '的伴侶是', author2.partner.name) except:print(author2.name, '還沒有伴侶')輸出:
黃夫人 的伴侶是 黃永祥 黃永祥 的伴侶是 黃夫人 王軍 還沒有伴侶總結(jié)
以上是生活随笔為你收集整理的Django(part32)--一对一映射的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Django(part31)--admi
- 下一篇: Django(part34)--一对多映