从 jinja 渲染的 html 模板生成 CSV table - 如何传递 python class 对象?
Generating CSV table from jinja rendered html template - how do I pass a python class object?
我正在尝试构建一个简单的 Flask Web 应用程序:
A) 使用关键字
搜索小型 postgres 数据库
B) returns 所有相关条目
C) 将条目呈现给浏览器
D) 用户可以将条目下载到 csv 文件中
我正在努力将 python 对象从 jinja 模板传递到 python 函数中。当我将对象从 jinja 模板传递给函数时,对象变成每个索引字符串的单个元素,不再具有属性 result.operation_name
和 result.project_num
。我用了
<a href="{{ url_for('core.downloadsearch',result=result) }}">Download Search</a>
传递对象result
.
这是一个问题,因为我想使用对象的属性 result
将不同的变量划分到 CSV 的单独单元格中。
或者,我通过 jinja 呈现的查询 html 传递给生成 csv 的 python 函数 - 它有效,但是,我不喜欢为单个任务查询数据库两次.感觉效率不高
如何在不将 python 对象从 jinja 成功传递到 python 函数的情况下将其转换为字符串?或者有没有更好的完全不同的数据流?
代码如下:
正在设置 db.Model:
class ProjectInfo(db.Model):
__tablename__ = 'project_info'
id = db.Column(db.Integer, primary_key=True, server_default=db.FetchedValue())
operation_name = db.Column(db.String, nullable=False, unique=True)
project_num = db.Column(db.String(10), nullable=False, unique=True)
def __init__(self, operation_name, project_num):
self.operation_name = operation_name
self.project_num = project_num
def __repr__(self):
return f"{self.operation_name},{self.project_num}"
查询数据库并传递给jina2模板list.html:
@core.route('/search', methods=['GET', 'POST'])
def search():
search_word = form.search.data
result = ProjectInfo.query.filter(ProjectInfo.operation_name.contains(search_word)).all()
return render_template('list.html', result=result)
在 jinja 呈现 list.html 中,呈现 results
内容并传递给 downloadsearch(csv generationg 函数):
{% block content %}
<div>
<h3>
<a href="{{ url_for('core.downloadsearch',result=result) }}">Download Search</a>
</h3>
<table>
<tbody>
{% for row in result %}
<tr><td>{{row.operation_name}}</td><td>{{row.project_num}}</td></tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
在python函数中生成csv文件:
def downloadsearch(result):
#result is now a single-element indexed string
#take result input and generate some csv
你不能这样做,url_for
会构建一个URL,所以你可以传递给它的数据将在URL中,你的对象将不会被序列化适合 URL.
从我的角度来看,将 search_word
传递到端点 downloadsearch
并从那里获取结果会更合乎逻辑。
此外,直接传递 result
意味着您信任客户端,并且出于安全原因永远不应信任客户端,因此此外,您还必须验证客户端发送的数据。
我正在尝试构建一个简单的 Flask Web 应用程序:
A) 使用关键字
搜索小型 postgres 数据库
B) returns 所有相关条目
C) 将条目呈现给浏览器
D) 用户可以将条目下载到 csv 文件中
我正在努力将 python 对象从 jinja 模板传递到 python 函数中。当我将对象从 jinja 模板传递给函数时,对象变成每个索引字符串的单个元素,不再具有属性 result.operation_name
和 result.project_num
。我用了
<a href="{{ url_for('core.downloadsearch',result=result) }}">Download Search</a>
传递对象result
.
这是一个问题,因为我想使用对象的属性 result
将不同的变量划分到 CSV 的单独单元格中。
或者,我通过 jinja 呈现的查询 html 传递给生成 csv 的 python 函数 - 它有效,但是,我不喜欢为单个任务查询数据库两次.感觉效率不高
如何在不将 python 对象从 jinja 成功传递到 python 函数的情况下将其转换为字符串?或者有没有更好的完全不同的数据流?
代码如下:
正在设置 db.Model:
class ProjectInfo(db.Model):
__tablename__ = 'project_info'
id = db.Column(db.Integer, primary_key=True, server_default=db.FetchedValue())
operation_name = db.Column(db.String, nullable=False, unique=True)
project_num = db.Column(db.String(10), nullable=False, unique=True)
def __init__(self, operation_name, project_num):
self.operation_name = operation_name
self.project_num = project_num
def __repr__(self):
return f"{self.operation_name},{self.project_num}"
查询数据库并传递给jina2模板list.html:
@core.route('/search', methods=['GET', 'POST'])
def search():
search_word = form.search.data
result = ProjectInfo.query.filter(ProjectInfo.operation_name.contains(search_word)).all()
return render_template('list.html', result=result)
在 jinja 呈现 list.html 中,呈现 results
内容并传递给 downloadsearch(csv generationg 函数):
{% block content %}
<div>
<h3>
<a href="{{ url_for('core.downloadsearch',result=result) }}">Download Search</a>
</h3>
<table>
<tbody>
{% for row in result %}
<tr><td>{{row.operation_name}}</td><td>{{row.project_num}}</td></tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
在python函数中生成csv文件:
def downloadsearch(result):
#result is now a single-element indexed string
#take result input and generate some csv
你不能这样做,url_for
会构建一个URL,所以你可以传递给它的数据将在URL中,你的对象将不会被序列化适合 URL.
从我的角度来看,将 search_word
传递到端点 downloadsearch
并从那里获取结果会更合乎逻辑。
此外,直接传递 result
意味着您信任客户端,并且出于安全原因永远不应信任客户端,因此此外,您还必须验证客户端发送的数据。