Django-20 關係映射 1. 一對一 2. 一對多 多對多

  • 在關係型數據庫中,通常不會把所有數據都放在同一張表中,不易於擴展,常見關係映射有:
    1,一對一映射:如身份證對應一個人
    2,一對多映射:一個班級可以有多個學生
    3,多對多映射:一個學生可以報多個課程,一個課程可以有多個學生學習

1. 一對一

創建

  • 一對一是表示現實事物間存在的一對一的對應關係。
  • 如:一個家庭只有一個戶主,一個男人有一個妻子,一個人有一個唯一的指紋等
  • 語法:OneToOneField(類名, on_delete=xxx)
class A(model.Model):
  ...
class B(model.Model):
  屬性 = models.OneToOneField(A,on_delete=xxx)
  • 特殊字段選項on_delete - 級聯刪除
    1. models.CASCADE 級聯刪除。Django模擬SQL約束ON DELETE CASCADE的行爲,並刪除包含ForeignKey的對象
    2. models.PROTECT 拋出ProtectedError 以阻止被引用對象的刪除;(等同於mysql默認的RESTRICT)
    3. SET_NULL設置ForeignKey null; 需要制定null=True
    4. SET_DEFAULT 將ForeignKey設置爲其默認值;必須設置ForeignKey的默認值。
      示例:
from django.db import models

class Author(models.Model):
  name = models.CharField('作家',max_length=50)

class Wife(models.Model):
  name = models.ChartField('妻子',max_length=50)
  author = models.OnToOneField(Author,on_delete=models.CASCADE)

創建數據

  • 無外鍵的模型類[Author]:
    author1 = Author.objects.create(name='王老師')
  • 有外鍵的模型類[Wife]:
    關聯obj:wife1 = Wife.objects.create(name='王夫人',author=author1)
    關聯主鍵:wife1 = Wife.objects.create(name='王夫人',author_id=1)

查詢數據

1,正向查詢:直接通過外鍵屬性查詢,則稱爲正向查詢

通過wife找author

from .models import Wife
wife = Wife.objects.get(name='王夫人')
wife.author.name
2. 反向查詢:沒有外鍵屬性的另一方,可以調用反向屬性查詢到關聯的另一方

反向關聯屬性爲 實例對象.引用類名(小寫),如作家的反向引用爲 作家對象.wife
當反向引用不存在時,則會觸發異常

author1 = Author.objects.get(name='王老師')
author1.wife.name

2. 一對多

一對多是表示現實事物間存在的一對多的對應關係
如:一個學校有多個班級,一個班級有多個學生,一本圖書只能屬於一個出版社,一個出版社允許出版多本圖書
一對多需要明確出具體角色,在多表上設置外鍵
當一個A對象可以關聯多個B對象時

class A(model.Model):
...
class B(model.Model):
  屬性 = models.ForeignKey("一"的模型類, on_delete=xx)

ForeignKey必須指定on_delete模式

示例

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)

創建數據

先創建“一”再創建“多”

from .models import *
pub1 = Publisher.objects.create('name'='清華大學出版社')
Book.objects.create(title='C++',publisher=pub1)
Book.objects.create(title='Java',publisher_id=1)

查詢數據

1,正向查詢[通過Book查詢Publisher]
通過publisher屬性查詢即可

book.publisher
abook = Book.objects.get(id=1)

2,反向查詢[通過Publisher查詢對應的所有Book]
需要用到反向屬性

pub1= Publisher.objects.get(name='清華大學出版社')
books = pub1.book_set.all()

多對多

多對多表達對象之間多對多複雜關係。如:每個人都有不同的學校(小學、初中、高中)每個學校都有不同的學生

  • mysql中創建多對多需要依賴第三張表來實現
  • Django中無需手動創建第三張表,Django自動完成

語法:在關聯的兩個類中的任意一個類中,增加

  • 屬性 = models.ManyToManyField(MyModel)

創建數據

方案1:先創建author再關聯book

author1 = Author.objects.create(name='呂老師')
author2 = Author.objects.create(name='王老師')
book11 = author1.book_set.create(title='Python')
author2.book_set.add(book11)

方案2:先創建book再關聯author

book = Book.objects.create(title='python1')
author3 = book.authors.create(name='guoxiaonao')
book.authors.add(author1)

查詢數據

1,正向查詢:有多對多屬性的對象查另一方
通過Book查詢對應的所有的Author
此時多對多屬性等價於objects
book.authors.all()->獲取book對應的所有author的信息
book.authors.filter(age__gt=80)->獲取book對應的作者中年齡大於80歲的信息
2,反向查詢
通過Author查詢對應的所有Book
利用反向屬性book_set
author.book_set.all()
author.book_set.filter()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章