python-flask结合bootstrap实现网页小工具实例-半小时速通版

参考:
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


目录

  • 背景&问题
  • 基础知识
    • helloworld
  • 解决思路
  • 关键点1:如何存放js文件
  • 关键点2:动态更新图像文件的路径
  • 关键点3:如何放置css文件

背景&问题

临时接到任务,需要写一个网页,该网页接受一个文字输入,向后台发出post请求,后台(linux系统)接收请求后调用一个可执行文件,获取执行结果(包含文字和图片),进行解析后再更新到当前网页中。因为不涉及数据库,也没有太复杂的操作,所以我决定用flask写。

虽然我之前写过django,但那是五年前的事情了,写网站我一直用的是java。所以我花了1h速通flask的基础操作+调试,终于解决了问题

本文除了有基础知识还有这个问题的解决思路,如果不想看基础知识可以直接跳转到解决思路部分。

基础知识

首先需要安装flask-bootstrap

pip install flask-bootstrap

因为是速通,所以直接上例子。相关知识会写在注释里。

helloworld

文件结构:
在这里插入图片描述
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 datavar 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, parsevar 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 commandcmdStr = "..."code = 1 # if fail, 0res = {}try:output = subprocess.check_output(cmdStr, shell=True, stderr=subprocess.STDOUT, universal_newlines=True)# parse outputexcept subprocess.CalledProcessError as e:code = 0# add some data...res["code"] = code# convert to json stringreturn json.dumps(res)

subprocess_check_output()参数说明:

  • command:这是一个字符串变量,包含要执行的命令。例如,command 可能是一个系统命令或者一个调用其他可执行文件的命令。
  • shell=True:这个参数告诉 subprocess 模块在一个 shell 中执行命令。如果设置为 False,则 command 将被当作一个可执行文件路径和参数列表来执行,而不是在 shell 中执行。
  • stderr=subprocess.STDOUT:这个参数指定将标准错误(stderr)重定向到标准输出(stdout)。这意味着标准错误将会和标准输出合并到一起,以便能够捕获所有输出。
  • universal_newlines=True:这个参数告诉 subprocess 将命令的输入和输出处理为文本模式而不是字节模式。这意味着执行结果将会是一个字符串,而不是一个字节串。
  • 返回值就是标准输出stdout。

关键点1:如何存放js文件

考虑到国内访问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>

关键点2:动态更新图像文件的路径

这个小工具需要经过计算才能产生图像文件,所以在静态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 imgfile_dir = curDir + '/static/output'return send_from_directory(file_dir, filename)

关键点3:如何放置css文件

放置在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路径下的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/1314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构——7.3 树形查找

7.3 树形查找 概念 二叉排序树&#xff08;BST&#xff09; 二叉排序树&#xff08;Binary Sort Tree&#xff0c;BST&#xff09;&#xff0c;又称为二叉查找&#xff08;搜索&#xff09;树&#xff08;Binary Search Tree&#xff09;&#xff0c;是一种特殊的二叉树&am…

FreeLearning C/C++ 译文集翻译完成

C 高级编程C 高级编程秘籍Qt Creator 应用开发C 游戏编程入门指南C 编程入门指南Boost.Asio C 网络编程Boost C 应用开发秘籍第二版C 数据结构与算法设计原理C Qt5 GUI 编程C 高性能编程C 反应式编程C 系统编程秘籍C 研讨会C 现代嵌入式编程秘籍C 专家编程&#xff1a;成为熟练…

Android,判断是否快速点击

问题背景 在Android控件中,如果快速点击容易造成一些不同的bug,尤其是那种在click事件中方有耗时操作的代码,容易引起anr,并且有些性能低的机器,在用户点击多次控件的时候很容易出现问题,在车机中也会导致回弹的一系列问题(这里面包括get到的信号导致回弹),针对于这种…

力扣---从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]示…

Rust常用特型之Borrow和BorrowMut特型

在Rust标准库中&#xff0c;存在很多常用的工具类特型&#xff0c;它们能帮助我们写出更具有Rust风格的代码。 std::borrow::Borrow和AsRef有点相似&#xff0c;如果一个类型实现了Borrow<T>&#xff0c;那么你可以从它的borrow函数里高效的借出一个&T。但是Borrow施…

synchronized和ReentrantLock傻傻分不清楚

synchronized和ReentrantLock都是用于线程间同步的机制&#xff0c;都是可重入锁&#xff08;同一个线程可以多次获取同一个锁&#xff09;&#xff0c;它们的异同点如下&#xff1a; 一、应用场景 1.synchronized可应用于实例方法、静态方法和代码块。 2.ReentrantLock 是 jav…

使用Docker搭建Redis主从集群

文章目录 ☃️前言☃️搭建❄️❄️架构❄️❄️实例说明❄️❄️搭建第一个服务器上的两个实例❄️❄️搭建第二个服务器上的一个实例 ☃️开启主从❄️❄️改配置❄️❄️重启从节点 ☃️验证 ☃️前言 单节点 Redis 的并发能力是有上限的&#xff0c;要进一步提高Redis的并…

了解监控易(33):工单管理

在复杂的IT运维环境中&#xff0c;高效、规范地处理各种事务请求至关重要。监控易的工单管理功能&#xff0c;作为一款轻量化的运维协同工具&#xff0c;为团队提供了一个集中化、标准化的平台&#xff0c;以创建、接单、转交、挂起和重启工单&#xff0c;从而确保客户设备故障…

搜维尔科技:SenseGlove 的 Nova 被用于组装卫星接收器的虚拟现实培训项目中

SenseGlove 的 Nova 被用于组装卫星接收器的虚拟现实培训项目中 搜维尔科技&#xff1a;SenseGlove 的 Nova 被用于组装卫星接收器的虚拟现实培训项目中 得益于 SenseGlove 的力反馈专利&#xff0c;学员可以感受到他们正在组装的零件的形状、尺寸和密度。学员可以通过运动跟踪…

[大模型]TransNormerLLM-7B FastApi 部署调用

TransNormerLLM-7B FastApi 部署调用 1. TransNormer 介绍 TransNormerLLM 是一个基于线性注意力的 LLM&#xff0c;在准确性和效率方面均优于传统的基于 softmax 注意力的模型。它是在包含多达1.4 万亿个令牌的高质量语料库上进行训练的&#xff0c;TransNormerLLM 从之前的…

K-means和DBSCAN

目录 一、K-means和DBSCAN之间的主要区别 二、DBSCAN聚类算法 2.1DBSCAN聚类算法实现点集数据的聚类 2.2DBSCAN聚类算法实现鸢尾花数据集的聚类 三、K-means聚类算法 3.1K-means聚类算法实现随机数据的聚类 3.2K-means聚类算法实现鸢尾花数据集的聚类 一、K-means和DBSC…

014Node.js时间格式包silly-datetime安装与使用

下载&#xff1a; https://www.npmjs.com/网站上下载silly-datetime 安装 npm i silly-datetime --save var sd require(silly-datetime);console.log(new Date()); //2024-04-18T04:40:38.505Zvar dsd.format(new Date(), YYYY-MM-DD HH:mm);console.log(d); //2024…

未加权的相位解包裹算法DCT-0基础入门(含matlab代码和详细教程解析)

后面会更新c++ 的代码 ! phi = phase_unwrap(psi, weight) % get the wrapped differences of the wrapped valuesdx = [zeros([size(psi,1),1]), wrapToPi(diff(psi, 1, 2)), zeros([size(psi,1),1])];dy = [zeros([1,size(psi,2)]); wrapToPi(diff(psi, 1, 1)); zeros([1,s…

idea在controller或者service使用ctrl+alt+b进入方法后,如何返回到 进入前的那一层

idea在controller或者service使用ctrlaltb进入方法后&#xff0c;如何返回到进入方法的最外层 解决方案使用 ctrlalt ← /→← /→ 键盘上的左右键盘

jQuery 选择器有几种,分别是什么

jQuery选择器是用于“选择”&#xff08;或查找&#xff09;HTML元素的强大工具。jQuery选择器基于元素的名称、ID、类、类型、属性等进行选择。以下是jQuery选择器的几种主要类型&#xff0c;以及它们的详细代码示例&#xff1a; 基本选择器&#xff1a; 元素选择器&#xff1…

2024.4.20力扣每日一题——组合总和

2024.4.20 题目来源我的题解方法一 回溯 题目来源 力扣每日一题&#xff1b;题序&#xff1a;39 我的题解 方法一 回溯 以每一个位置开始深搜&#xff0c;直到target等于0或者小于0或者遍历完结束。 关键在于&#xff1a;注意去重 巧妙方法&#xff1a;传入一个index&#x…

stm32中断发送接收数据

配置hal库 1配置时钟 2配置uart 3打开中断 程序结构 uart中断函数 中断接收和发送函数 HAL_UART_Receive_IT()&#xff1a;启动中断驱动的接收过程&#xff0c;当接收到指定数量的字节后会产生中断&#xff0c;并调用HAL_UART_RxCpltCallback()回调函数。 HAL_StatusTypeD…

Qt : 如何解决重载引起的歧义

一、引子 在Qt中编写代码&#xff0c;进行信号和槽函数的连接时&#xff0c;如果采用新的语法&#xff0c;如&#xff1a; connect(ui->doubleSpinBox, &QDoubleSpinBox::valueChanged,this,&App::minValueChanged);当你准备快乐编译时&#xff0c;突然被背刺。卧槽…

【Redis(6)】Redis集群模式配置示例

Redis的三种高可用方案对比参考上一篇博客&#xff1a;深入理解Redis三种高可用方案&#xff0c;以做出明智的选择&#xff0c;下面要探讨的是三种方案其中的一种。 在构建高性能缓存系统时&#xff0c;Redis以其卓越的速度和灵活性成为首选。然而&#xff0c;传统的哨兵模式和…

STL分解

效果图 ref&#xff1a;时序数据分析的利器——STL分解 - 知乎 (zhihu.com)