Flask实现仅当PostgreSQL列有数据时显示下载按钮
实现Flask模板中仅当cert_obj非空时显示下载按钮(无需JavaScript)
核心思路是利用Flask的Jinja2模板引擎的条件渲染功能,在服务器端生成HTML时直接判断cert_obj是否非空,决定是否渲染下载按钮,完全不需要前端JavaScript。
1. 后端查询数据(优化建议)
你的查询语句已能获取cert_obj字段,建议将查询结果转换为字典列表,方便模板通过键名访问字段,提升代码可读性:
from flask import Flask, render_template, request, redirect, Response import psycopg2 app = Flask(__name__) @app.route('/') def show_certificates(): # 替换为你的数据库配置 conn = psycopg2.connect( dbname="your_database", user="your_user", password="your_password", host="localhost" ) cur = conn.cursor() # 执行查询语句 query = """ SELECT c.id, c."name", c."date", c.description, EXTRACT('Day' FROM (date::DATE) - now()), cert_obj FROM certificate c """ cur.execute(query) # 转换为字典列表 column_names = ['id', 'name', 'date', 'description', 'days_diff', 'cert_obj'] certificates = [dict(zip(column_names, row)) for row in cur.fetchall()] cur.close() conn.close() return render_template('certificates.html', certificates=certificates)
2. 前端模板条件渲染按钮
在HTML模板(如certificates.html)中,遍历证书数据时,通过Jinja2的{% if %}语句判断cert_obj是否非空,仅满足条件时渲染下载按钮:
<table class="table table-striped"> <thead> <tr> <th>ID</th> <th>名称</th> <th>日期</th> <th>描述</th> <th>天数差</th> <th>操作</th> </tr> </thead> <tbody> {% for cert in certificates %} <tr> <td>{{ cert.id }}</td> <td>{{ cert.name }}</td> <td>{{ cert.date }}</td> <td>{{ cert.description }}</td> <td>{{ cert.days_diff }}</td> <td> {# 同时判断None和空字符串,覆盖PostgreSQL空值和空内容场景 #} {% if cert.cert_obj is not none and cert.cert_obj != '' %} <form method="POST" action="/download-cert"> <input type="hidden" name="cert_id" value="{{ cert.id }}"> <input class="btn btn-primary form-control" type="submit" value="Download" name="change"> </form> {% endif %} </td> </tr> {% endfor %} </tbody> </table>
3. 后端下载路由实现
添加处理下载请求的路由,根据提交的证书ID获取cert_obj内容并生成下载响应:
@app.route('/download-cert', methods=['POST']) def download_cert(): cert_id = request.form.get('cert_id') if not cert_id: return redirect('/') conn = psycopg2.connect( dbname="your_database", user="your_user", password="your_password", host="localhost" ) cur = conn.cursor() # 查询对应证书内容和名称(用于生成文件名) cur.execute("SELECT cert_obj, name FROM certificate WHERE id = %s", (cert_id,)) cert_data = cur.fetchone() cur.close() conn.close() if not cert_data or not cert_data[0]: return redirect('/') # 根据cert_obj实际类型调整响应参数(示例为文本文件) return Response( cert_data[0], mimetype='text/plain', headers={ "Content-disposition": f"attachment; filename={cert_data[1]}_certificate.txt" } )
关键说明:
- PostgreSQL中的
NULL值在Python中解析为None,模板中同时判断cert_obj is not none和cert_obj != '',覆盖空值和空字符串场景。 - 所有判断逻辑在服务器端完成,前端拿到的是最终渲染后的HTML,完全无需JavaScript参与。
内容的提问来源于stack exchange,提问作者Alex K
相关产品推荐
相关产品推荐

