学习flask/vue配合展示mysql数据

想了解一下前端vue.js加后端flask展示mysql数据大体流程,就让chatgpt给了一个例子,然后做了一些修改。不过为了调试的时候被一个问题卡了很久,看来chatgpt给出的示例代码也不是完全可靠。

准备数据库

  • 启动mysql的docker,同时做端口映射和密码配置
admin@osu-2:~/web$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=mysql_admin -p 13306:3306  -d mysql:8.0.32-debian
021a61a789ff4ef03d2f893727b2af269a2d4f55ec63f1f3fdd830d81fb07533
admin@osu-2:~/web$ 
  • 进入mysql
admin@osu-2:~/web$ mysql -h127.0.0.1 -P 13306 -uroot -pmysql_admin
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.32 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
  • 创建db和table
mysql> create database test;
Query OK, 1 row affected (0.01 sec)

mysql> use test;
Database changed
mysql>

mysql> CREATE TABLE person (id INT(10), name VARCHAR(20),age INT(3));
Query OK, 0 rows affected, 2 warnings (0.03 sec)

mysql> 
  • 写入熊大和熊二的信息
mysql> INSERT INTO person (id,name,age) VALUES (1,'XIONGDA',11);
Query OK, 1 row affected (0.02 sec)

mysql> INSERT INTO person (id,name,age) VALUES (2,'XIONGER',10);
Query OK, 1 row affected (0.01 sec)

mysql> 
mysql> select * from person;
+------+---------+------+
| id   | name    | age  |
+------+---------+------+
|    1 | XIONGDA |   11 |
|    2 | XIONGER |   10 |
+------+---------+------+
2 rows in set (0.00 sec)

mysql> 

准备代码

  • 安装好需要的包
admin@osu-2:~/web$ sudo apt-get install libmysqlclient-dev nodejs npm -y
admin@osu-2:~/web$ pip3 install mysql sqlalchemy flask
  • 源码文件,一个app.py,还有一个index.html放在templates目录下
admin@osu-2:~/web$ tree
.
├── app.py
└── templates
    └── index.html

1 directory, 2 files
admin@osu-2:~/web$ 
  • 文件内容
admin@osu-2:~/web$ cat app.py 
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Integer, String, DateTime, Column
from sqlalchemy.orm import declarative_base

from flask import Flask, jsonify, render_template

Base = declarative_base()
class PersonTable(Base):
    __tablename__ = 'person'
    id = Column(Integer,primary_key=True)
    name = Column(String, nullable=False)
    age = Column(Integer, nullable=False)
engine = create_engine('mysql+pymysql://', connect_args={'user': 'root',
                                                     'password': 'mysql_admin',
                                                     'host': '127.0.0.1',
                                                     'port': 13306,
                                                     'database': 'test',
                                                     'charset': 'utf8'})
DBSession = sessionmaker(bind=engine)
session = DBSession()

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/api/data')
def api_data():
    data = session.query(PersonTable).all()
    result = []
    for row in data:
        result.append({
            'id': row.id,
            'name': row.name,
            'age': row.age
        })
    print(jsonify(result))
    return jsonify(result)

if __name__ == '__main__':
    app.run(host='0.0.0.0')

admin@osu-2:~/web$ 
admin@osu-2:~/web$ cat templates/index.html 
<!DOCTYPE html>
<html>
  <head>
    <title>Flask Vue.js Example</title>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/axios@0.21.1/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app">
      <table border="1">
        <thead>
          <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Age</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="user in users">
            <td>{{ user.id }}</td>
            <td>{{ user.name }}</td>
            <td>{{ user.age }}</td>
          </tr>
        </tbody>
      </table>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            users: [],
          };
        },
        mounted() {
          axios.get('/api/data').then((response) => {
            this.users = response.data;
          });
        },
      });
      app.mount('#app');
    </script>
  </body>
</html>
admin@osu-2:~/web$ 

调试

第一次调试

  • 运行app.py
admin@osu-2:~/web$ python3 app.py 
 * Serving Flask app 'app'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.122.83:5000
Press CTRL+C to quit
  • web访问,发现报错
[2023-02-21 13:26:41,478] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "/home/admin/.local/lib/python3.8/site-packages/flask/app.py", line 2528, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/admin/.local/lib/python3.8/site-packages/flask/app.py", line 1825, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/admin/.local/lib/python3.8/site-packages/flask/app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/admin/.local/lib/python3.8/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
  File "app.py", line 27, in index
    return render_template('index.html')
  File "/home/admin/.local/lib/python3.8/site-packages/flask/templating.py", line 147, in render_template
    return _render(app, template, context)
  File "/home/admin/.local/lib/python3.8/site-packages/flask/templating.py", line 130, in _render
    rv = template.render(context)
  File "/home/admin/.local/lib/python3.8/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "/home/admin/.local/lib/python3.8/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "/home/admin/web/templates/index.html", line 20, in top-level template code
    <td>{{ user.id }}</td>
  File "/home/admin/.local/lib/python3.8/site-packages/jinja2/environment.py", line 485, in getattr
    return getattr(obj, attribute)
jinja2.exceptions.UndefinedError: 'user' is undefined
192.168.122.1 - - [21/Feb/2023 13:26:41] "GET / HTTP/1.1" 500 -
  • 为了定位这个报错,花费了很多时间,最后才意识到是Jinja2和js的变量都用{{}}来标识,导致被误以为是jinja2的变量

第二次调试

  • 找到一篇文章提出了三种解决方法,选择第二种,在div外加raw和endraw
admin@osu-2:~/web$ cat templates/index.html 
<!DOCTYPE html>
<html>
  <head>
    <title>Flask Vue.js Example</title>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/axios@0.21.1/dist/axios.min.js"></script>
  </head>
  <body>
    {% raw %}
    <div id="app">
      <table border="1">
        <thead>
          <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Age</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="user in users">
            <td>{{ user.id }}</td>
            <td>{{ user.name }}</td>
            <td>{{ user.age }}</td>
          </tr>
        </tbody>
      </table>
    </div>
    {% endraw %}
    <script>
      const app = Vue.createApp({
        data() {
          return {
            users: [],
          };
        },
        mounted() {
          axios.get('/api/data').then((response) => {
            this.users = response.data;
          });
        },
      });
      app.mount('#app');
    </script>
  </body>
</html>
admin@osu-2:~/web$ 
  • 重新运行app.py后,浏览器访问,可以看到存储在mysql的信息展示在web上了
    在这里插入图片描述
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值