目录

Flask学习笔记四-Flask与数据库连接

Flask学习笔记(四): Flask与数据库连接

Flask学习笔记(四): Flask 与数据库连接

前言

前面我们学习了 Flask 如何构建一个程序的流程,又研究了它的路由如何设定,还对如何获取模板表单数据进行了梳理,值得一提的就是 FlaskSQLAlchemy 的对接做得比较好,接下来将研究一下如何将 Flask 与数据库连接。

创建数据库

在系统中安装 mysql 数据库,通过 root 帐号进入数据库中,创建新的数据库 studentinfo

 create database studentinfo default character set utf8mb4 collate utf8mb4_unicode_ci;

这语句后面的 character 是设定数据库字符集。

安装 flask-sqlalchemy

flask-sqlalchemy ,这是 Flask 的一个插件,也相当于 FlaskSQLAlchemy 的一个接口,安装代码如下:

 pip3 install flask-sqlalchemy

安装 pymysql

为了使 Python 能和 mysql 数据库连接起来,需要安装 pymysql

pip3 install pymysql

创建数据表

首先要导入相应的包:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

接着创建与数据库的接口:

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@localhost:3306/studentinfo?charset=utf8'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True # 这一行如果不添加,程序会报警告。
db= SQLAlchemy(app)

所创建的 db 就是一个抽象的数据库对象, db=SQLAlchemy(app) 这一句即完成了将 Flask 与数据库的连接。

db 对象构造一个 Student 类:

class Student(db.Model):
     id     = db.Column(db.Integer, primary_key = True)
     name   = db.Column(db.String(100))
     sex = db.Column(db.String(100))
     studentId = db.Column(db.String(100))
     chinese = db.Column(db.String(200))
     math   = db.Column(db.String(100))
     english = db.Column(db.String(100))
     def __init__(self, name, sex, studentId, chinese, math, english): # __init__方法负责对象的初始化
         self.name = name
         self.sex = sex
         self.studentId = studentId
         self.chinese = chinese
         self.math = math
         self.english = english
db.create_all() # 将上述类映射到数据库中:

这时我们来 mysql 看看我们创建的表是否存在,进入数据库中输入: describe student

https://i-blog.csdnimg.cn/blog_migrate/7f31caac8575e4e0bf229f7027c83f14.png

添加数据

在创建数据表完成后,开始对数据库进行操作,首先来添加数据,为了添加方便,我们需要添加一个学生信息添加界面, info.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>学生信息</title>
</head>
<body>
    <h1>学生信息添加界面</h1>
     <form action = "{{ request.path }}" method = "post">
        <p><label for="name">姓名:</label><input type="text" name="name"></p>
        <p><label for="studentId">学号:</label><input type="text" name="studentId"></p>
        <p><label for="sex">性别</label><input type="radio" name="sex" value="男"><input type="radio" name="sex" value="女"></p>
        <p><label for="chinese">语文</label><input type="number" name="chinese"></p>
        <p><label for="math">数学</label><input type="number" name="math"></p>
        <p><label for="english">英语</label><input type="number" name="english"></p>
        <input type="submit" name="" value="添加">
    </form>
</body>
</html>

这一次我们将表单的 action 直接指向当前路径,这就要求在当前路径所对应的函数中,对 POST 数据进行处理:

@app.route('/newstudent/', methods = ['GET', 'POST'])
def newstudent():
    if request.method == 'POST':
        if request.form['name'] and request.form['studentId'] and request.form['sex'] and request.form['chinese'] and request.form['math'] and request.form['english']:
            curuser = Student(request.form['name'], request.form['studentId'], request.form['sex'], request.form['chinese'], request.form['math'], request.form['english'])
            db.session.add(curuser)
            db.session.commit()
            return redirect(url_for('AllStudent'))
    return render_template('info.html')

如果学习过 SQLAlchemy 的同学,应该对 session.add 以及 session.commit 这两个方法比较熟悉,在 SQLAlchemy 中, session 是通过 sessionmakeengine 进行绑定后的实例化对象,而在 flask-sqlalchemy 中,这个 session 就直接通过 db 就可以访问。

添加数据的界面如下:

https://i-blog.csdnimg.cn/blog_migrate/2efc0e6a60eeb4a0ba6a0d00a754d93f.png

显示学生数据信息

这里我们需要写一个页面来显示学生信息,在上述 newstudent 的路由函数中,当添加成功后,页面将会重定向至这个页面函数中: allinfo.html

<!DOCTYPE html>
<html>
<head>
     <meta charset="UTF-8">
    <title>学生信息列表</title>
</head>
<body>
    <h1>学生信息列表</h1>
     <h3>新建 (<a href = "{{ url_for('newstudent') }}">增加学生</a>)</h3>
    <table border="1">
        <thead>
          <tr>
            <th>姓名</th>
            <th>学号</th>
            <th>性别</th>
            <th>语文</th>
            <th>数学</th>
            <th>英语</th>
          </tr>
        </thead>
        <tbody>
         {% for student in students %}
          <tr>
            <td>{{ student.name }}</td>
            <td>{{ student.studentId }} </td>
            <td> {{ student.sex }} </td>
            <td>{{ student.chinese }} </td>
            <td> {{ student.math }} </td>
            <td>{{ student.english }} </td>
          </tr>
         {% endfor %}
        </tbody>
    </table>
</body>
</html>

添加一个路由:

@app.route('/allstudent/')
def AllStudent():
   return render_template('allinfo.html', students = Student.query.all() )

上述代码中,我们向模板增加了一个 Student 的变量,该变量将数据查询信息传递给模板 allinfo.html

显示的结果如下:

https://i-blog.csdnimg.cn/blog_migrate/211970ef852194fc9e890d63c5ca947b.png

在数据库中输入 select * from student 查询学生信息:

https://i-blog.csdnimg.cn/blog_migrate/14e3edc3b0d761e7b4951d899288dceb.png

可以看到,数据已经存入数据库中。

修改数据和删除数据

所有学生信息是以表格的形式呈现的,现在其最后一列插入修改和删除的链接,要注意,这个链接我们是用 url_for 来实现的,因为每个学生信息的 id 唯一,因此无论修改还是删除,都需要将学生信息的 id 放在 url_for 的参数中进行传递,同时要注意,采用 url_for 进行参数传输时,是进行 GET 提交,所以在相应的路由中,要加入 GETPOST 方法, allinfo.html 修改如下:

<!DOCTYPE html>
<html>
<head>
     <meta charset="UTF-8">
    <title>学生信息列表</title>
</head>
<body>
    <h1>学生信息列表</h1>
     <h3>新建 (<a href = "{{ url_for('newstudent') }}">增加学生</a>)</h3>
    <table border="1">
        <thead>
          <tr>
            <th>姓名</th>
            <th>学号</th>
            <th>性别</th>
            <th>语文</th>
            <th>数学</th>
            <th>英语</th>
              <th>操作</th>
          </tr>
        </thead>
        <tbody>
         {% for student in students %}
          <tr>
            <td>{{ student.name }}</td>
            <td>{{ student.studentId }} </td>
            <td> {{ student.sex }} </td>
            <td>{{ student.chinese }} </td>
            <td> {{ student.math }} </td>
            <td>{{ student.english }} </td>
              <td><a href = "{{ url_for('modifystudent', studentid=student.id) }}">修改</a>&nbsp;&nbsp;<a href = "{{ url_for('deletestudent', studentid=student.id) }}">删除</a></td>
          </tr>
         {% endfor %}
        </tbody>
    </table>
</body>
</html>

添加相应的路由

上述模板中插入的两个链接中有两个函数被 url_for 当做参数来做路由,一个是 modifystudent ,一个是 deletestudent ,这两个函数都带有参数 studentid

modifystudent 模块:

@app.route('/modifystudent/<studentid>/', methods = ['GET', 'POST'])
def modifystudent(studentid):
     curuser = db.session.query(Student).filter_by(id=studentid).one()
     if request.method == 'POST':
         if request.form['studentId'] and request.form['sex'] and request.form['chinese'] and  request.form['math'] and request.form['english']:
             curuser.studentId   = request.form['studentId']
             curuser.sex = request.form['sex']
             curuser.chinese = request.form['chinese']
             curuser.math = request.form['math']
             curuser.english = request.form['english']
             db.session.commit()
             return redirect(url_for('AllStudent'))
     return render_template('modifyinfo.html', curuser=curuser)

deletestudent 模块:

@app.route('/deleteuser/<studentid>/')
def deletestudent(studentid):
     db.session.query(Student).filter_by(id=studentid).delete()
     db.session.commit()
     return redirect(url_for('AllStudent'))

测试

运行一下项目,然后访问一下:

https://i-blog.csdnimg.cn/blog_migrate/eed51fa6307cb63b325fd042b0e644cc.png

这里可以看到,已经有了修改和删除操作,下面进行测试:

https://i-blog.csdnimg.cn/blog_migrate/2d907c078dd2da1a8440e41f98804ed9.png

https://i-blog.csdnimg.cn/blog_migrate/10f7d48f6f858c3fdaa27b6196b283f3.png

小结

本文实现了flask连接数据库,并且实现了一个简单的学生信息管理操作。