使用Flask在HTML/JS上呈现SQL数据

Rod*_*ele 0 html javascript python google-maps flask

我创建了一个简单的Web应用程序,它打算从sql数据库中提取数据(特别是在美国的森林火灾事件和相关元数据).我可以使用flask/sqlite3在Python中查询数据库,并打印与查询匹配的结果列表.但是,我不熟悉如何获取结果列表并动态地在谷歌地图上呈现它.因此,对于返回的每个记录,将有一个带有lat/long的标记,然后是一个显示元数据的对话框.

相关片段:

@app.route('/results', methods=['POST'])
def results():
    form_input = {
        'start_date': request.form['yearfrom'] + '-' + request.form['monthfrom'] + '-' + request.form['dayfrom']
                      + 'T00:00:00',
        'end_date': request.form['yearto'] + '-' + request.form['monthto'] + '-' + request.form['dayto']
                      + 'T00:00:00',
        'state': request.form['state'],
        'fire_size': request.form['size']
    }
    # Stores only query terms without blank values
    query_terms = {k: v for k, v in form_input.items() if v != 'blank' and k != 'start_date' and k != 'end_date'}

    query_string = 'SELECT latitude,longitude, fire_name, discovery_date, stat_cause_descr, fire_size, state FROM fires' \
                   ' WHERE ' + " ".join(["%s='%s' and" % (key, value) for (key, value)
                    in query_terms.items()]) + ' discovery_date BETWEEN ' + "'%s'" % form_input['start_date'] \
                   + ' and ' + "'%s'" % form_input['end_date']

    query = query_db(query_string, one=False)
    pp.pprint(query)
    return render_template('results.html', fire_name=query[0]['fire_name'])
Run Code Online (Sandbox Code Playgroud)

打印"查询"返回:

[   {   'discovery_date': '2013-01-01T00:00:00',
        'fire_name': 'VOYAGER',
        'fire_size': 0.1,
        'latitude': 34.56083333,
        'longitude': -118.67833333,
        'stat_cause_descr': 'Equipment Use',
        'state': 'CA'},
    {   'discovery_date': '2013-01-01T00:00:00',
        'fire_name': 'MIDDLE',
        'fire_size': 1.0,
        'latitude': 33.077,
        'longitude': -111.75919,
        'stat_cause_descr': 'Arson',
        'state': 'AZ'},
    {   'discovery_date': '2013-01-01T00:00:00',
        'fire_name': 'GLACIER 13',
        'fire_size': 0.5,
        'latitude': 47.624939,
        'longitude': -103.415214,
        'stat_cause_descr': 'Miscellaneous',
        'state': 'ND'},
Run Code Online (Sandbox Code Playgroud)

因此检索正在按预期工作.我知道在return语句中我需要指定要在html上呈现的术语...我只是不确定如何遍历所有返回的记录以为每个记录显示一个标记.我非常欣赏一些方向.

dav*_*ism 5

不是将一个结果传递给模板,而是传递整个集合.然后使用Jinja块循环结果.

return render_template(template, fires=query)
Run Code Online (Sandbox Code Playgroud)

打印每个火名称的基本示例:

{% for fire in fires %}
    {{ fire['fire_name'] }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

如果您已经拥有JSON兼容集合并需要将JSON传递给JavaScript代码,则可以使用一些内置的Jinja过滤器.

var fires = {{ fires|tojson|safe }};
Run Code Online (Sandbox Code Playgroud)

不相关,您的查询现在对注入攻击开放.您应该使用参数化查询,而不是使用字符串格式来插入用户输入.

query = 'select * from user where username = ?'
result = cursor.execute(query, ('davidism',))
Run Code Online (Sandbox Code Playgroud)

一个更强大的解决方案是使用Flask-SQLAlchemy或其他ORM代替将表映射到类并使用函数而不是字符串构建查询.


通过使用Flask-WTF之类的表单库,您可以更轻松地使用表单数据,它将呈现表单,并为您验证和转换输入.