Django數(shù)據(jù)映射(一對一,一對多,多對多)
數(shù)據(jù)表關(guān)聯(lián)關(guān)系映射
常用的表關(guān)聯(lián)方式有三種:
一對一映射
如: 一個身份證對應(yīng)一個人
一對多映射
如: 一個班級可以有多個學生
多對多映射
如: 一個學生可以報多個課程,一個課程可以有多個學生學習
一對一映射
- 一對一是表示現(xiàn)實事物間存在的一對一的對應(yīng)關(guān)系。
- 如:一個家庭只有一個戶主,一個男人有一個妻子,一個人有一個唯一的指紋信息等
語法
class A(model.Model):
...
class B(model.Model):
屬性 = models.OneToOneField(A, on_delete=xxx)
外鍵類字段選項
特殊字段參數(shù)【必須項】:
on_delete
- models.CASCADE 級聯(lián)刪除。 Django模擬SQL約束ON DELETE CASCADE的行為,并刪除包含F(xiàn)oreignKey的對象。
- models.PROTECT 拋出ProtectedError 以阻止被引用對象的刪除;[等同于mysql默認的RESTRICT]
- models.SET_NULL 設(shè)置ForeignKey null;需要指定null=True
- models.SET_DEFAULT 將ForeignKey設(shè)置為其默認值;必須設(shè)置ForeignKey的默認值。
- … 其它參請參考文檔 https://docs.djangoproject.com/en/2.2/ref/models/fields/#foreignkey
其余常用的字段選項【非必須項】;如:
- null
- unique 等
用法示例
創(chuàng)建作家和作家妻子類
# file : xxxxxxxx/models.py
from django.db import models
class Author(models.Model):
? ? '''作家模型類'''
? ? name = models.CharField('作家', max_length=50)
class Wife(models.Model):
? ? '''作家妻子模型類'''
? ? name = models.CharField("妻子", max_length=50)
? ? author = models.OneToOneField(Author, on_delete=models.CASCADE) ?# 增加一對一屬性?創(chuàng)建一對一的數(shù)據(jù)記錄
from .models import * author1 = Author.objects.create(name='王老師') wife1 = Wife.objects.create(name='王夫人', author=author1) # 關(guān)聯(lián)王老師 author2 = Author.objects.create(name='小澤老師') # 一對一可以沒有數(shù)據(jù)對應(yīng)的數(shù)據(jù)
數(shù)據(jù)查詢
正向查詢
直接通過關(guān)聯(lián)屬性查詢即可
# 通過 wife 找 author from .models import Wife wife = Wife.objects.get(name='王夫人') print(wife.name, '的老公是', wife.author.name)
反向查詢
- 通過反向關(guān)聯(lián)屬性查詢
- 反向關(guān)聯(lián)屬性為實例對象.引用類名(小寫),如作家的反向引用為作家對象.wife
- 當反向引用不存在時,則會觸發(fā)異常
# 通過 author.wife 關(guān)聯(lián)屬性 找 wife,如果沒有對應(yīng)的wife則觸發(fā)異常
author1 = Author.objects.get(name='王老師')
print(author1.name, '的妻子是', author1.wife.name)
author2 = Author.objects.get(name='小澤老師')
try:
print(author2.name, '的妻子是', author2.wife.name)
except:
print(author2.name, '還沒有妻子')
一對多映射
- 一對多是表示現(xiàn)實事物間存在的一對多的對應(yīng)關(guān)系。
- 如:一個學校有多個班級,一個班級有多個學生, 一本圖書只能屬于一個出版社,一個出版社允許出版多本圖書
語法
當一個A類對象可以關(guān)聯(lián)多個B類對象時
class A(model.Model):
? ? ...
class B(model.Model):
? ? 屬性 = models.ForeignKey("一"的模型類, on_delete=xx)用法示例
有二個出版社對應(yīng)五本書的情況.
清華大學出版社 有書
- C++
- Java
- Python
北京大學出版社 有書
- 西游記
- 水滸
創(chuàng)建模型類
# file: otm/models.py
from django.db import models
class Publisher(models.Model):
?? ?'''出版社【一】'''
? ? name = models.CharField('名稱', max_length=50, unique=True)
class Book(models.Model):
? ? '''書【多】'''
? ? title = models.CharField('書名', max_length=50)
? ? publisher = ForeignKey(Publisher, on_delete=models.CASCADE)創(chuàng)建數(shù)據(jù)
#先創(chuàng)建 '一' ,再創(chuàng)建 '多' from .models import * pub1 = Publisher.objects.create(name='清華大學出版社') Book.objects.create(title='C++', publisher=pub1) Book.objects.create(title='Java', publisher_id=1) #高級創(chuàng)建 - 利用 反向?qū)傩? pub2 = Publisher.objects.create(name='北京大學出版社') pub2.book_set.create(title='西游記')
數(shù)據(jù)查詢
通過 Book 查詢 Publisher【正向】
通過 publisher 屬性查詢即可 ???????book.publisher abook = Book.objects.get(id=1) print(abook.title, '的出版社是:', abook.publisher.name)
通過 Publisher 查詢 對應(yīng)的所有的 Book 【反向】
Django會在Publisher中增加一個屬性來表示對對應(yīng)的Book們的查詢引用
屬性:book_set 等價于 objects
# 通過出版社查詢對應(yīng)的書
pub1 = Publisher.objects.get(name='清華大學出版社')
books = pub1.book_set.all() # 通過book_set 獲取pub1對應(yīng)的多個Book數(shù)據(jù)對象
#books = Book.objects.filter(publisher=pub1) # 也可以采用此方式獲取
print("清華大學出版社的書有:")
for book in books:
print(book.title)
多對多映射
多對多表達對象之間多對多復(fù)雜關(guān)系,如: 每個人都有不同的學校(小學,初中,高中,…),每個學校都有不同的學生…
語法
在關(guān)聯(lián)的兩個類中的任意一個類中,增加:
屬性 = models.ManyToManyField(MyModel)
用法示例
- 一個作者可以出版多本圖書
- 一本圖書可以被多名作者同時編寫
class Author(models.Model): ? ? ... class Book(models.Model): ? ? ... ? ? authors = models.ManyToManyField(Author)
創(chuàng)建模型類
class Author(models.Model):
'''作家模型類'''
name = models.CharField('作家', max_length=50)
def __str__(self):
return self.name
class Book(models.Model):
'''書模型類'''
title = models.CharField('書名', max_length=50)
authors = models.ManyToManyField(Author)
def __str__(self):
return self.title
創(chuàng)建數(shù)據(jù)
方案1 先創(chuàng)建 author 再關(guān)聯(lián) book
author1 = Author.objects.create(name='呂老師')
author2 = Author.objects.create(name='王老師')
# 呂老師和王老師同時寫了一本Python
book11 = author1.book_set.create(title="Python")
author2.book_set.add(book11)
方案2 先創(chuàng)建 book 再關(guān)聯(lián) author
book = Book.objects.create(title='python1')
#郭小鬧和呂老師都參與了 python1 的 創(chuàng)作
author3 = book.authors.create(name='guoxiaonao')
book.authors.add(author1)
數(shù)據(jù)查詢
通過 Book 查詢對應(yīng)的所有的 Author【正向】
book.authors.all() -> 獲取 book 對應(yīng)的所有的author的信息
book.authors.filter(age__gt=80) -> 獲取book對應(yīng)的作者中年齡大于80歲的作者的信息
通過 Author 查詢對應(yīng)的所有的Book【反向】
Django會生成一個反向?qū)傩?book_set 用于表示對對應(yīng)的book的查詢對象相關(guān)操作
author.book_set.all() author.book_set.filter()
到此這篇關(guān)于Django數(shù)據(jù)映射(一對一,一對多,多對多)的文章就介紹到這了,更多相關(guān)Django 數(shù)據(jù)映射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Windows 安裝 Anaconda3+PyCharm的方法步驟
這篇文章主要介紹了Windows 安裝 Anaconda3+PyCharm的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-06-06

