赞
踩
参考:
Python之flask结合Bootstrap框架快速搭建Web应用_支持bootstrap的python软件-CSDN博客
https://blog.csdn.net/lovedingd/article/details/106696832
Bootstrap 警告框 | 菜鸟教程
https://www.runoob.com/bootstrap/bootstrap-alert-plugin.html
flask框架的Jinja2中怎么动态的传入图片啊? - 清风徐来的回答 - 知乎
https://www.zhihu.com/question/478883018/answer/2052587300
二十:jinja2之加载静态文件 - 向前走。 - 博客园
https://www.cnblogs.com/zhongyehai/p/11784648.html
Flask jinja2.exceptions.TemplateSyntaxError: 语法错误|极客笔记
https://deepinout.com/flask/flask-questions/129_flask_jinja2exceptionstemplatesyntaxerror_expected_token_end_of_print_statement_got_posted.html
环境:
win10 / centos6 , python3
临时接到任务,需要写一个网页,该网页接受一个文字输入,向后台发出post请求,后台(linux系统)接收请求后调用一个可执行文件,获取执行结果(包含文字和图片),进行解析后再更新到当前网页中。因为不涉及数据库,也没有太复杂的操作,所以我决定用flask写。
虽然我之前写过django,但那是五年前的事情了,写网站我一直用的是java。所以我花了1h速通flask的基础操作+调试,终于解决了问题。
本文除了有基础知识还有这个问题的解决思路,如果不想看基础知识可以直接跳转到解决思路部分。
首先需要安装flask-bootstrap
。
pip install flask-bootstrap
因为是速通,所以直接上例子。相关知识会写在注释里。
文件结构:
myflask.py
from flask import Flask, render_template, request from flask_bootstrap import Bootstrap import subprocess import os # template_folder: store *.html app = Flask(__name__, template_folder=os.getcwd() + "/static/templates") bootstrap = Bootstrap(app) @app.route('/index') def index(): return render_template('index.html') @app.route('/') def index1(): return "hello" if __name__ == '__main__': app.run(host="0.0.0.0", port=8080) # 如果报错的话可以考虑换成 # app.run(debug=True, host="127.0.0.1", port=8080)
注意:查资料的时候有说template_folder
设为""就是当前路径,然后把*.html
放到/static/templates
下就能找到。我试了,找不到。。所以还是选择指明。
index.html
{% extends "bootstrap/base.html" %} {% block title %}Flask{% endblock %} {% block navbar %} <p>带有下拉菜单的标签</p> <ul class="nav nav-tabs"> <li class="active"><a href="#">Home</a></li> <li><a href="#">SVN</a></li> <li><a href="#">iOS</a></li> <li><a href="#">VB.Net</a></li> <li class="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" href="#"> Java <span class="caret"></span> </a> <ul class="dropdown-menu"> <li><a href="#">Swing</a></li> <li><a href="#">jMeter</a></li> <li><a href="#">EJB</a></li> <li class="divider"></li> <li><a href="#">分离的链接</a></li> </ul> </li> <li><a href="#">PHP</a></li> </ul> {% endblock %}
注意:base.html相当于一个基础性的模板。我们写的时候先用extend
表示继承,然后用标签提示每块是什么内容。比如被{%- block styles %}
和{%- endblock styles %}
包裹的地方就是写css文件路径的地方(参见关键点3)。这个模板在类似这样的安装路径下:
D:\ProgramData\Anaconda3\Lib\site-packages\flask_bootstrap\templates\bootstrap
执行后控制台输出为:
访问 ip:8080/
访问 ip:8080/index,可以看到bootstrap已经用上了。
首先构建一个form,提交按钮的click函数是:
$("#input-design-submit").click(function () { // get some data var seq = $(this).attr("data-seq"); if (seq && seq.length>10 && seq.length < 10000) { $.ajax({ type: 'POST', url: "/run_command", data: { sq: seq }, success: function (resp) { // do sth, like unpack, parse var obj = jQuery.parseJSON(resp); var code = obj.code; ... } }); } else { return false; } });
然后在后台写提交的路由:
curDir = os.getcwd() @app.route('/run_command', methods=['POST']) def run_command(): if request.method == 'POST': #print(request.form) # make command cmdStr = "..." code = 1 # if fail, 0 res = {} try: output = subprocess.check_output(cmdStr, shell=True, stderr=subprocess.STDOUT, universal_newlines=True) # parse output except subprocess.CalledProcessError as e: code = 0 # add some data... res["code"] = code # convert to json string return json.dumps(res)
subprocess_check_output()
参数说明:
考虑到国内访问cdn可能会慢,所以把用到的js提前下载好,保存到本地。
首先需要指定static_folder
:
app = Flask(__name__, template_folder = curDir + "/static/templates", static_folder = curDir + "/static")
然后把*js
放到指定好的位置。
在前端引用:
<!--script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script-->
<!--script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script-->
<script src="{{ url_for('static', filename='jquery.min.js') }}"></script>
<script src="{{ url_for('static', filename='bootstrap.min.js') }}"></script>
这个小工具需要经过计算才能产生图像文件,所以在静态html里是不知道的。我采取的是路径映射的办法。
当前端发出post请求,收到回复后,动态加载一个<img>
,大概写作:
const arr = ['<p><img src="', imgsrc, '" width="49%" alt="404"/></p><p>', desc, "</p>"]
$("#output-res").html(arr.join(''));
$("#output-res").show();
其中imgsrc和desc是两个经过解析得到的字符串;output-res
是一个原本隐藏的div
,需要加载图片的时候再显示。
假设imgsrc的格式是:"/output/" + name + ".gif"
,我的图像文件放在python文件根目录/static/output
下,那么只要再写一个路径映射,利用flask包的send_from_directory
函数就可以让图像正确显示了。
需要注意的是,send_from_directory()
需要同时传递路径和文件名。
@app.route('/output/<filename>')
def uploaded_files(filename):
# for img
file_dir = curDir + '/static/output'
return send_from_directory(file_dir, filename)
放置在block head中:
{%- block head %}
{%- block styles %}
<!-- Bootstrap -->
<!-- 在线的写法 -->
<!--link href="{{bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')}}" rel="stylesheet"-->
<link href="{{ url_for('static', filename='bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet">
{%- endblock styles %}
{%- endblock head %}
注意:如果想要在保留bootstrap格式的情况下增加新格式,需要保留第一个链接。此时css文件是放在主函数中写的、static路径下的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。