Flask-多對多關係

看了第四遍Miguel Grinberg寫的《Flask Web》一書,前面部分都非常順利,但到了關注者這一章,被多對多關係卡住了。在寫本篇博客時我腦子裏還是一團漿糊,邊寫邊想吧。

在說多對多關係之前,先回顧一下一對多關係

一對多

拿之前的章節來說,有兩張表,分別是Role表和User表。
Role表:普通用戶,管理員
User表:用戶名,郵件,地址,電話。。。

我們知道,一個用戶只能有一種角色,但一種角色可以有多個用戶。
即:一個角色對應多個用戶。

粗略地使用SQLAlchemy構建一對多關係就是

class Role(db.Model):
    ...
    users = db.relationship('User', backref='role')

class User(db.Model):
    ...
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
  • 外鍵的值就是另一張表的主鍵值,通過這樣一種相同值將2張表聯結起來
  • 關係表的設計:保證一類一表,用相同值(外鍵)聯結在一起

上面的代碼表示,我們在User表中添加了外鍵(role_id列),它的值指向roles表的主鍵(id列),這樣,user可以通過role_id的值來獲取其角色內容

多對多關係

先來看多對多關係的實際應用:學生選課
一名學生可以選擇多門課,
一門課也同時有多名學生選擇
學生選課就是一個多對多的關係。你怎麼用student表和class表來表示這個多對多的關係?先想想看怎麼加這個外鍵,因爲外鍵纔是聯結兩表的重要部分。

學生表

學號 姓名
1
2
3

課程表

課程號 課程
101
102
103

如果在學生表裏加個class_id(課程號)

學號 姓名 課程號
1 101
2 101
3 102

你會發現,一名學生只能選擇一門課,一門課可以被多個學生選擇。
反之,如果你在課程表里加個學號,那也只能表示,一門課只有一名學生。所以只有2張表的話,外鍵是不好加進去的。

解決方法:添加第3張表,我們稱之爲“”關聯表“”。

關聯表學號 關聯表課程號
1 101
1 102
2 101
3 102
2 103

這他媽不就是一一對應的表嘛!!(滑稽)
儘管這有點滑稽,但是它卻能完美解決我們的問題

  1. 一個學生有多個記錄,但一個記錄只能屬於一個學生。
  2. 一個課程有多個記錄,但一個記錄也只能有一個課程

這就是關聯表的作用,將多對多拆分成兩個一對多。

SQLAlchemy實現:
這裏寫圖片描述

幾點說明

1.關聯表就是一張簡單的表,不是模型,所以注意寫法
2.多對多關係可以在任意一側定義關係,這裏是在student表裏定義
3.secondary參數爲關聯表名
4.backref會自動處理另一側的反向引用,所以你看class表那麼簡潔

現在查詢就變的簡單了。
要查小明選的所有課:小明.classes.all()
要查所有上語文課的學生:語文.students.all()
如果小明再選一門數學:小明.classes.add(數學)
如果小明退選一門化學:小明.classes.remove(化學)

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