第七章、模型詳解 -- 模型關係

數據庫實體間有3種對應關係:一對一,一對多,多對多。

  • 一對一關係: 一個學生對應一個學生檔案編號
  • 一對多關係: 一個學生只屬於一個班級,但一個班級有多名學生

學生表中添加班級號字段作爲外鍵,與班級表的主鍵關聯

  • 多對多關係: 一個學生可以選擇多門課,一門課也有多名學生選擇。

在多對多關係中,通過添加字段無法解決問題,需要創建額外的關係表來連接相關數據表
刪除數據時,要先刪除關係表中的記錄,再刪除主表中的記錄

模型類中處理3種關係

  • 一對一:使用OneToOneField()函數,將字段定義在任意模型類中。
  • 一對多:使用ForeignKey()函數,將字段定義在多的模型類中
  • 多對多:使用ManyToManyField()函數,將字段定義在任意模型類中
  • 可以維護遞歸的關聯關係,使用self指定

一對多關係: 一對一關係可以看作一對多的特例

修改models.py文件中的PersonInfo類,添加hbook屬性
ORM會在app_personinfo表中增加hbook_id字段作爲外鍵,並關聯到app_bookinfo表的id主鍵

說明:如果生成遷移文件報錯,將migrations目錄中除init之外的文件刪除

 

class PersonInfo(models.Model):
    ...
    hbook = models.ForeignKey('BookInfo', on_delete=models.CASCADE)

增加測試數據

 

INSERT INTO app_personinfo(pname, pgender, pcomment, isDelete, hbook_id) VALUES
('曹操',1,'字孟德',0,1),
('劉備',1,'字玄德',0,1),
('諸葛亮',1,'字孔明',0,1),
('孫權',1,'字仲謀',0,1),
('賈寶玉',1,'榮國府公子',0,2),
('林黛玉',0,'金陵十二釵之冠',0,2),
('薛寶釵',0,'薛姨媽之女',0,2),
('王熙鳳',0,'賈璉之妻',0,2),
('賈母',0,'寶玉祖母',0,2),
('宋江',1,'呼保義',0,3),
('盧俊義',1,'玉麒麟',0,3),
('吳用',1,'智多星',0,3),
('公孫勝',1,'入雲龍',0,3),
('孫悟空',1,'唐僧的大徒弟',0,4),
('唐僧',1,'玄奘',0,4),
('豬八戒',1,'悟能',0,4),
('沙僧',1,'沙悟淨',0,4);

多對多關係:

models.py文件中增加新聞類型類新聞類
一個新聞類型下可以用多條新聞,一條新聞可以屬於多種新聞類型

 

新聞類型
class TypeInfo(models.Model):
    tname = models.CharField(max_length=20)  # 新聞類別

新聞
class NewsInfo(models.Model):
    ntitle = models.CharField(max_length=60)  # 新聞標題
    ncontent = models.TextField()  # 新聞內容
    npub_date = models.DateTimeField(auto_now_add=True)  # 新聞發佈時間

    # 通過ManyToManyField建立TypeInfo類和NewsInfo類之間多對多的關係
    typeinfo= models.ManyToManyField('TypeInfo')

執行數據遷移後,自動創建3張表:

  • app_typeinfo:新聞類型表
  • app_newsinfo:新聞表
  • app_newsinfo_typeinfo:關係表

說明:如果要指定關係表的名字,可以使用througt參數

添加測試數據

 

新聞類型
INSERT INTO app_typeinfo(tname) VALUES
('科技'),
('軍事'),
('國際')

新聞
INSERT INTO app_newsinfo(ntitle, ncontent, npub_date) VALUES
('互聯網科技','馬雲已退出阿里旗下5家公司:官方稱沒這個打算','2018-7-24'),
('數碼產品','蘋果官方科普來了:全面認識Apple ID','2018-6-23'),
('宇宙探索','平行時空、多元宇宙真的存在?令人細思極恐','2018-5-24'),
('國際軍情','美國國會議員:前總統吉米·卡特請纓親赴朝鮮','2017-11-24'),
('中國軍情','中國海軍萬噸鉅艦的起點 原型就是這艘民船','2016-5-24'),
('歐洲','歐盟高官警告:特朗普不要搞垮了世貿體系','2017-2-24'),
('美國','伊拉克北部發生汽車炸彈襲擊致1死7傷','2016-5-24')

關係表
INSERT INTO app_newsinfo_ntype(newsinfo_id, typeinfo_id) VALUES
(1,1),
(3,1),
(5,1),
(4,2),
(6,2),
(2,3),
(4,3),
(6,3),
(7,3)

實例演示: 使用SQL語句,查詢所有新聞標題、內容及其類型

 

SELECT n.ntitle, n.ncontent, t.tname
FROM app_newsinfo n, app_typeinfo t, app_newsinfo_ntype nt
WHERE n.id = nt.newsinfo_id AND t.id = nt.typeinfo_id

 

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