上篇文章學習了Flask框架——模型關系(一對多關系),這篇文章我們學習Flask框架——模型關系(多對多關系)。
我們拿學生和課程為例子,一個學生可以選多門課程,一門課程可以被多名學生選,所以它們是多對多關系,我們假設數據庫中學生表與課程表如下圖所示:
如何使這兩張表建立聯系呢,是在課程表中多加一個字段來表示哪個學生選了這門課嗎?
假如是在課程表中多加一個字段,每門課只能被一個學生選,那么該怎么辦好呢?
想要兩張表建立聯系,多加一個字段不行的話,那么我們多建一張表不就好了嗎?如下圖所示:
通過創建第三張表來使學生表與課程表建立關系,第三張表我們稱為關系表,數據庫是這樣設計,那么如何使模型之間產生聯系呢,如何編寫模型之間產生聯系的代碼呢?
在編寫模型類代碼之前,首先我們創建一個Flask項目,其目錄如下所示:
創建好項目后,我們開始編寫配置文件settings.py的代碼,如下所示:
class Configs:
ENV='development'
DEBUG=True
# 設置連接數據庫路徑
SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:123456@127.0.0.1:3306/test'
# 每次請求結束后自動提交數據庫中的改動
SQLALCHEMY_COMMIT_ON_TEARDOWN=True
# 禁用SQLAlchemy對追蹤對象的修改并且發送信號
SQLALCHEMY_TRACK_MODIFICATIONS = False
編寫好配置文件后,我們將配置文件導入app.py文件中,代碼如所示:
from flask import Flask
from settings import Config
app = Flask(__name__)
app.config.from_object(Config) # 加載配置
編寫模型類
好了,Flask框架的基礎配置已經寫好了,接下來我們在app.py文件中編寫學生模型類與課程模型類,代碼如下所示:
from flask_sqlalchemy import SQLAlchemy
# 創建映射對象db
db=SQLAlchemy(app=app,use_native_unicode="utf8")
#Student模型類
class Student(db.Model):
__tablename__ = 'student' # 數據表名
id=db.Column(db.Integer,primary_key=True) #學生id
name=db.Column(db.String(20),nullable=False) #學生名
password=db.Column(db.Integer,nullable=False) #密碼
#Course模型類
class Course(db.Model):
__tablename__='course' #數據表名
id=db.Column(db.Integer,primary_key=True) #課程id
course_name=db.Column(db.String(50),nullable=False) #課程名
credit=db.Column(db.Float,nullable=False) #學分
students = db.relationship('Student', backref='course', secondary='student_course') #設置studens字段,使Course模型類與Student模型類產生聯系
這里我們在Course模型類中添加了students字段,該字段使用了db.relationship()方法讓Course模型與Student模型產生了聯系,當然也可以在Student模型類中添加course字段并使用db.relationship()方法使Student模型與Course模型產生聯系,在Student模型類添加字段代碼如下所示:
course = db.relationship('Course', backref='student', secondary='student_course')
其中:
- 'Course'參數是你要產生聯系的模型類;
- backref是反向引用,其值可以是任意字符,該字符很重要,可以調用關聯模型類的屬性字段;
- secondary的值是關系數據表的表名。
注意:db.relationship()方法只能在兩個相關聯的模型類中任意選擇一個調用,也就是說只能在Course模型類或者Student模型類中調用。
好了,學生模型類和課程模型類已經寫好了,不知道你們有沒有發現,學生模型與課程模型都沒有設置外鍵的代碼,這是因為外鍵要設置在關系數據表中,接下來編寫關系數據表的模型類代碼,代碼如下所示:
#第三張數據表模型類
class Student_Course(db.Model):
__tablename__='student_course' #數據表名
id=db.Column(db.Integer,primary_key=True) #id
student_id=db.Column(db.Integer,db.ForeignKey('student.id')) #學生id
course_id=db.Column(db.Integer,db.ForeignKey('course.id')) #課程id
當還有其他模型類要關聯時,只要在上面的模型類添加外鍵字段即可。
除了這樣設置關系數據表外,我們還可以通過db.Table()方法來設置,代碼如下所示:
tags=db.Table('student_course', #數據表名
db.Column('id',db.Integer,primary_key=True) #id
db.Column('student_id',db.Integer,db.ForeignKey('student.id')), #學生id
db.Column('course_id',db.Integer,db.ForeignKey('course.id')) #課程id
)
其中:student_id為數據表的字段,db.Integer為字段的數據類型,這里是整型,db.ForeignKey()方法傳遞的是模型類.模型類主鍵。
好了,模型類代碼已經寫好了,接下來我們通過在app.py中編寫代碼創建數據表,其代碼如下所示:
if __name__ == '__main__':
db.create_all() #創建數據表
app.run()
在終端執行app.py后,就成功創建好數據表了,下面我們在pycharm中看看這三張表的聯系,如下圖所示:
這樣就成功把student數據表與course數據表聯系起來了,我們手動為這三張表添加數據,如下圖所示:
接下來我們將通過學生來找出該學生選的課程和通過課程來找出該課程被哪些學生。
通過學生找課程
首先編寫視圖函數,代碼如下所示:
@app.route('/findcourse')
def course():
student_id=request.args.get('id') #獲取學生id
student=Student.query.get(student_id) #獲取學生數據
return render_template('course.html',student=student) #通過render_template()方法將course.html完整地呈現在網頁中,并傳遞student學生數據到網頁中
編寫好視圖函數后,接下來在templates文件夾中創建一個名為course的html文件,其代碼如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>學生找已選課程</title>
</head>
<body>
學生名:{{ student.name }}
<br>
該學生選了以下課程:
{% for course in student.course %}
<p>{{ course.course_name }}---{{ course.credit }}學分</p>
{% endfor %}
</body>
</html>
第八行代碼,我們將傳遞過來的student中獲取學生名,在第十一行代碼中,我們利用Course模型類中的反向引用backref參數值course,通過student.course就可以獲取課程對象,通過課程對象來獲取課程名、課程學分。在終端執行app.py,并在瀏覽器中打開http://127.0.0.1:5000/findcourse?id=2022001,如下圖所示:
這里我們找了學號為2022001,其選了Python程序設計、數據分析、數據可視化。
通過課程找學生
首先編寫視圖函數,代碼如下所示:
@app.route('/findstudent')
def student():
course_id=request.args.get('id') #獲取課程id
courses=Course.query.get(course_id) #獲取課程數據
return render_template('student.html',courses=courses) #通過render_template()方法將student.html完整地呈現在網頁中,并傳遞courses學生數據到網頁中
編寫好視圖函數后,接下來在templates文件夾中創建一個名為student的html文件,其代碼如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>通過課程找學生</title>
</head>
<body>
課程名:{{ courses.course_name }}
<br>
選擇該課程的學生有:
{% for student in courses.students %}
<p>{{ student.name }}---學號:{{ student.id }}</p>
{% endfor %}
</body>
</html>
第八行代碼,通過傳遞的courses數據獲取課程名,第十一行代碼,使用了Course模型類中students字段,通過courses.students獲取到了學生對象,再通過學生對象獲取學生名、學號。
在終端執行app.py,并在瀏覽器中打開http://127.0.0.1:5000/findstudent?id=003,如下圖所示:
這里我們獲取課程id為003,其學生有張三,學號為2022001。
通過關系數據表使另外兩張數據表產生了聯系,并可以互相獲取到數據。
好了,Flask框架——模型關系(多對多關系)就講到這里了,下篇文章繼續學習Flask框架——Session與Cookie,感謝觀看!!!
公眾號:白巧克力LIN