You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python读取本地Postgres数据并渲染到HTML卡片页面

实现方案:读取PostgreSQL记录并渲染为页面卡片

1. 调整后端路由逻辑

你现有代码仅在POST提交时执行插入操作,没有在返回页面前查询数据库记录的逻辑,需要补充查询逻辑并将结果传递给前端模板。另外你当前拼接SQL字符串的写法存在SQL注入风险,替换为参数化查询更安全。
修改后的后端代码参考:

import time
import psycopg2
from flask import request, render_template
# 提前定义好数据库连接地址、arduino实例等全局配置

def home():
    # 原有Arduino读取逻辑保持不变
    time.sleep(1)
    arduinoData = arduino.readline().decode('ascii')
    arduino.inWaiting()
    print(arduinoData)
    arduinoData = arduinoData[:2]

    records = []
    # 用with上下文管理数据库连接,自动处理连接关闭,避免资源泄漏
    with psycopg2.connect(connection_address) as connection:
        cursor = connection.cursor()

        if request.method == 'POST':
            serie = request.form.get('serie')
            print(serie)
            # 用参数化查询替代字符串拼接,避免SQL注入
            insert_sql = "INSERT INTO registros (serie, carril) VALUES (%s, %s);"
            cursor.execute(insert_sql, (serie, arduinoData))
            connection.commit()
            arduino.flushInput()
        
        # 无论GET/POST请求,都查询全量记录传给前端,字段名和实际表结构对齐即可
        cursor.execute("SELECT id, serial_number, date, serie, carril FROM registros ORDER BY date DESC;")
        # fetchall返回所有查询结果,每条记录为元组格式:(id, serial_number, date, serie, carril)
        records = cursor.fetchall()

    return render_template("home.html", records=records)

注意:上述SQL里的字段名请和你Postgres表实际字段名完全匹配,如果建表时给大小写敏感的字段名加了双引号,查询时也要对应加双引号,否则会报字段不存在错误。

2. 调整前端模板,循环渲染卡片

你当前写的是单张静态卡片,用Jinja2的{% for %}语法遍历后端传递的records列表,每条记录生成一张卡片,把静态占位符替换为实际字段值即可。
修改后的home.html模板参考:

<div class="container-custom">
  <div class="row row-cols-2 row-cols-md-12 g-4">
    <!-- 遍历所有记录生成卡片 -->
    {% for record in records %}
    <div class="col-sm-auto">
      <div class="card" style="width: 10rem;">
        <div class="progress">
            <!-- 进度条数值可根据实际业务逻辑替换,此处保留示例值 -->
            <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 75%">75%</div>
        </div>
        <div>
            <!-- 展示日期字段,元组索引从0开始:0=id,1=serial_number,2=date,3=serie,4=carril -->
            <p>{{ record[2].strftime('%Y-%m-%d %H:%M') if record[2] else '无时间记录' }}</p>
        </div>
        <div class="card-body">
          <!-- 替换为需要展示的序列号、车道等实际数据 -->
          <p class="card-text">序列号:{{ record[1] }}</p>
          <p class="card-text">车道:{{ record[4] }}</p>
        </div>
      </div>
    </div>
    {% endfor %}
  </div>
</div>

可选优化点

  • 可以将游标替换为字典格式游标(引入psycopg2.extras.RealDictCursor),查询返回的每条记录都是字典格式,模板中可以直接通过{{ record.字段名 }}的方式取值,不用记忆元组索引位置,降低出错概率
  • 如果需要页面自动展示最新插入的记录,可以在HTML的<head>标签中添加<meta http-equiv="refresh" content="5">实现每5秒自动刷新页面,后续需要无刷新更新时再替换为AJAX异步拉取方案
  • 建议给Arduino读取、数据库操作部分添加异常捕获逻辑,避免串口读取失败、数据库连接异常时直接抛出错误导致页面不可用

内容的提问来源于stack exchange,提问作者Dayreff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 15:48:22