2018-05-25

Django模型關(guān)系

  • 1:1

    • OneToOneField
    • 內(nèi)部實現(xiàn)
      • 使用外鍵,F(xiàn)oreignKey實現(xiàn)
      • 對外鍵添加了一個唯一約束
    • 數(shù)據(jù)添加
      • 主表未添加數(shù)據(jù)而從表添加數(shù)據(jù)時,系統(tǒng)會報錯(1602)違反了唯一性約束
      • 報錯后主表添加后,從表添加時id變?yōu)橹鞅韎d+(報錯次數(shù))
      • 原因是數(shù)據(jù)在存儲時會先報錯后判斷,再刪除,但仍然會占用id資源
    • 數(shù)據(jù)刪除
      • 默認(rèn)

        • CASECADE
        • 當(dāng)聲明關(guān)系的表中數(shù)據(jù)被刪除,關(guān)聯(lián)表數(shù)據(jù)不會受影響
        • 當(dāng)被關(guān)聯(lián)的表中的數(shù)據(jù)被刪除,關(guān)系表數(shù)據(jù)會被級聯(lián)刪除
      • PROTECT(在關(guān)系屬性中設(shè)置)

        • 主表數(shù)據(jù)如果存在級聯(lián)數(shù)據(jù),主表就不能刪除
        • 當(dāng)主表數(shù)據(jù)不存在級聯(lián)數(shù)據(jù),主表數(shù)據(jù)允許刪除
        • 開發(fā)中推薦使用這種方式
      • SET(在一對一關(guān)系中無法使用,因為存在唯一約束)

        • DEFAULT
        • NULL
        • XXX
      • 主從表

        • 聲明關(guān)系的就是從表
        • 哪張表聲明關(guān)系,哪張表就相對來說不重要
      • 級聯(lián)數(shù)據(jù)獲取

        • 從表獲取主表

          • 通過顯性屬性進(jìn)行獲取
          • 顯示屬性是關(guān)系,關(guān)心就是我們關(guān)聯(lián)到的主表的對象
        • 主表獲取從表

          • 隱性屬性(就是關(guān)聯(lián)表的模型名(小寫))

          • 通過隱性屬性獲取

          • 屬性值就是從表的對象

          • 方法二:

            • 通過從表對象獲取
            • 從表對象=模型類.objects.get(隱性id=num)
            • 通過關(guān)系查詢往往會降低查詢性能,所以此方法相當(dāng)于對數(shù)據(jù)查詢進(jìn)行優(yōu)化
  • 1:M

    • ForeignKey
    • 內(nèi)部實現(xiàn)
      • 真的就是使用了外鍵實現(xiàn)的
      • 沒有了一對一的約束
    • 刪除數(shù)據(jù)
      • 默認(rèn)
      • CASECADE
        • 主表刪除數(shù)據(jù),從表級聯(lián)的所有數(shù)據(jù)消失
        • 從表刪除數(shù)據(jù),主表不受影響
      • SET_NULL(前提條是字段屬性可以為空,null=Ture)
        • 主表刪除數(shù)據(jù),從表級聯(lián)的所有數(shù)據(jù)的關(guān)系id變?yōu)閚ull
      • SET_DEFAULT(設(shè)置default時必須設(shè)置存在的pk,一般為系統(tǒng)設(shè)置的默認(rèn)值)
        • 主表刪除數(shù)據(jù),從表級聯(lián)的所有數(shù)據(jù)的關(guān)系id變?yōu)閐efault值
      • 數(shù)據(jù)查詢
        • 多獲取一
          • 使用的顯性屬性,屬性值就是一的對象
          • 可以直接使用
        • 一獲取多
          • 使用的是隱性屬性
          • 一對象.級聯(lián)數(shù)據(jù)_set(級聯(lián)數(shù)據(jù)為級聯(lián)模型名(小寫)),是一個Manager的子類RelatedManager對象
          • 可以支持Manager篩選操作
          • all( )
          • filter( )
          • exclude( )
          • order_by( )
          • Manager支持的操作,都支持
          • 支持 remove(關(guān)系字段允許為空)(必須先獲取后移除,結(jié)果為被刪除學(xué)生的關(guān)系id字段值為null)
            • clear
            • add(添加時注意:被添加對象從objects對象中用get(pk=num)獲取)
  • M:N

    • 多對多
      • 使用ManyToManyField
      • 如果兩張表的關(guān)系為多對多,會生成額外的第三張表,作為關(guān)系表兩,記錄的是兩張表的pk_id
      • 關(guān)系表中 UNIQUE(xx,yy)
        • (1,1),(1,2),(1,3)
        • (2,1),(2,2),(3,2)
        • (2,2)不能添加
        • 兩張表的PK_id可以相等,但不能有重復(fù)的添加(特點:添加重復(fù)不報錯)
      • 多對多也是外鍵實現(xiàn)的
      • 在多對多的關(guān)系中,使用兩個外鍵實現(xiàn)
    • 主從表各自添加數(shù)據(jù)
      • 多對多模型關(guān)系中主表和從表的添加之間不存在特定關(guān)系
      • 從表的關(guān)系屬性數(shù)據(jù)添加不需要指定,故可以忽略
    • 從表(聲明關(guān)系的表)添加到主表
      • 各自查詢自己的對象
      • 從表對象.從表關(guān)系屬性不再是單一的主表對象(可以理解為主表對象集合)
      • 變成了一個ManyRelatedManager下的對象
        • add( )
        • clear( )
        • remove( )
        • all( )
        • filter( )
        • exclude( )
        • get ( )
      • 查詢使用的是顯性屬性
    • 主表添加到從表
      • 是一個Manager是隱性屬性
      • 主表對象.從表模型名_set 對象屬于ManyRelatedManager這個類 (可以理解為從表對象的一個集合對象)
        • add ( )
        • all ( )
        • remove ( )
    • 刪除數(shù)據(jù)
      • 不管主表還是從表數(shù)據(jù)刪除,都不會互相影響
      • 刪除自己的數(shù)據(jù),并且刪除關(guān)系表中的數(shù)據(jù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容