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 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()参数说明:

  • 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 img
    file_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路径下的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用C#写一个读取pdf文档内容的库

安装这两个库&#xff0c;第二个库一定要安装否则有些pdf文件读取会出现异常 读取 using iText.Kernel.Pdf; using iText.Kernel.Pdf.Canvas.Parser; using iText.Kernel.Pdf.Canvas.Parser.Listener;namespace TestReadPdf {public static class PdfHelper{public static IE…

算法刷题day46

目录 引言一、树的重心二、毕业旅行问题三、高精度乘法 引言 今天复习了一下高精度的所有模板&#xff0c;包括加法、减法、乘法、除法&#xff0c;因为自己当时在蓝桥杯的时候没有看出来那个题使用高精度&#xff0c;因为对于一个数的大小和一个数的长度&#xff0c;自己有时…

关于卡尔曼滤波进行状态预测的方法

卡尔曼滤波是一种有效的线性动态系统状态估计方法。它通过递归地处理测量数据&#xff0c;结合系统动力学模型和测量模型&#xff0c;来预测和估计系统的状态。卡尔曼滤波特别适用于系统状态在时间上演化&#xff0c;而且测量数据存在噪声的情况。以下是卡尔曼滤波对于状态预测…

编译器的学习

常用的编译器&#xff1a; GCCVisual CClang&#xff08;LLVM&#xff09;&#xff1a; Clang 可以被看作是建立在 LLVM 之上的一个项目, 实际上LLVM是clang的后端&#xff0c;clang作为前端前端生成LLVM IR&#xff0c;https://zhuanlan.zhihu.com/p/656699711MSVC &#xff…

[C++][算法基础]能被整除的数(容斥原理)

给定一个整数 &#x1d45b; 和 &#x1d45a; 个不同的质数 &#x1d45d;1,&#x1d45d;2,…,&#x1d45d;&#x1d45a;。 请你求出 1∼&#x1d45b; 中能被 &#x1d45d;1,&#x1d45d;2,…,&#x1d45d;&#x1d45a; 中的至少一个数整除的整数有多少个。 输入格式…

【Java Spring MVC项目异常解决】HTTP 500

HTTP 500状态码表示“内部服务器错误”&#xff08;Internal Server Error&#xff09;。这是一个通用的错误响应&#xff0c;表明服务器在处理请求时遇到了预料之外的情况&#xff0c;导致无法完成请求。500错误是服务器端错误的一种&#xff0c;与客户端无关。在Web开发中&am…

初识《list》及手搓模拟《list》

目录 前言&#xff1a; 1. list的介绍及使用 list的介绍&#xff1a; list的使用&#xff1a; 1、list的构造​编辑 2、list iterator的使用 3、list capacity 4、list element access 5、list modifiers 2.list的模拟实现 1、关于迭代器&#xff1a; 2、迭代器类的…

代码质量与可维护性的重要性都有哪些?

目录 一、为了提高代码质量&#xff0c;可以采取以下几种方法&#xff1a; 二、如何制定和执行有效的代码编写规范&#xff1f; 三、设计模式和设计原则在提高代码质量中的具体应用案例有哪些&#xff1f; 四、代码审查的最佳实践和技巧是什么&#xff1f; 五、如何有效地…

CV每日论文--2024.4.24

1、Guess The Unseen: Dynamic 3D Scene Reconstruction from Partial 2D Glimpses 中文标题&#xff1a;猜测未见之景&#xff1a;从部分二维片段进行动态三维场景重建 简介&#xff1a;这篇论文提出了一种方法&#xff0c;可以从单目视频输入中重建世界和多个动态人物的3D模…

猫主食罐要怎么挑?注意这些含胶的罐头!

我曾与专业的宠物医生深入交流&#xff0c;得知猫罐头的种类与选择不可一概而论。主食罐头营养搭配精细&#xff0c;旨在全面满足猫咪健康需求&#xff0c;常添加矿物质和维生素&#xff0c;并针对不同猫咪有特定配方。而零食罐头更重口感与美味&#xff0c;钠含量高&#xff0…

如何提取单片机片内程序的值进行拷贝?

对于许多单片机&#xff0c;其固件是由制造商保护的&#xff0c;并且未经授权的访问、拷贝或修改可能侵犯法律。我这里有一套嵌入式入门教程&#xff0c;不仅包含了详细的视频 讲解&#xff0c;项目实战。如果你渴望学习嵌入式&#xff0c;不妨点个关注&#xff0c;给个评论222…

跨部门协作中的沟通困境与平台建设策略——以软硬件研发为例

一、背景 在科技行业&#xff0c;跨部门合作的重要性不言而喻&#xff0c;然而实际工作中&#xff0c;经常会遭遇沟通不畅的现象。以软件与硬件研发部门为例&#xff0c;两者在产品研发过程中经常需要紧密协作&#xff0c;但却时常出现信息传递障碍。当你试图阐述观点时&#…

LangSmith帮助测试大模型系统

LangSmith是评估大模型能力好坏的评估工具,能够量化评估基于大模型的系统的效果。LangSmith通过记录langchain构建的大模型应用的中间过程,从而能够更好的调整提示词等中间过程做优化。想要使用LangSmith首先进入他的设置页面,https://smith.langchain.com/settings注册一个…

多商家AI智能名片商城系统(开源版)——构建高效数字化商业新生态

一、项目概述 1、项目背景 1&#xff09;起源 随着数字化时代的快速发展&#xff0c;传统名片和商城系统已经难以满足企业日益增长的需求。商家需要更高效、更智能的方式来展示自己的产品和服务&#xff0c;与消费者进行互动和交易。同时&#xff0c;开源技术的普及也为开发…

安卓玩机工具推荐----MTK芯片 简单制作线刷包 备份分区 备份基带 去除锁类 推荐工具操作解析

工具说明 在前面几期mtk芯片类玩机工具中解析过如何无官方固件从手机抽包 制作线刷包的步骤&#xff0c;类似的工具与操作有很多种。演示的只是本人片面的理解与一些步骤解析。mtk芯片机型抽包关键点在于..mt*****txt的分区地址段引导和 perloader临时分区引导。前面几期都是需…

在控制台实现贪吃蛇

在控制台实现贪吃蛇 前备知识Win32APICOORD这个结构体的声明如下&#xff1a;GetStdHandle 函数GetConsoleCursorInfo 函数SetConsoleCursorInfo 函数 SetConsoleCursorPosition 函数getAsyncKeyState 函数 控制台窗口的大小以及字符打印介绍控制台中的坐标宽字符及本地化介绍s…

多线程情况下IBMMQ报文丢失原因分析

背景 最近工作中&#xff0c;使用IBMMQ&#xff0c;重启服务时有偶发性的报文丢失情况&#xff0c;应用从队列中获取到了消息&#xff0c;但是线程停止没有处理。 分析 消息处理线程流程&#xff1a; 判断线程状态是否可用&#xff0c;如果不可用直接返回。使用MQQueue.get…

Seurat -- Introduction to scRNA-seq integration 跟随学习记录

文章目录 数据是如何转换的原始ifnb数据对象Splits object后的数据对象数据对象构建完成后的标准流程Normalization后的数据对象scale 后的数据对象 不同的样本进行整合JoinLayers干了什么 数据是如何转换的 seurat object 中assays R N A l a y e r s RNAlayers RNAlayersco…

卡尔曼滤波器(一):卡尔曼滤波器简介

观看MATLAB技术讲座笔记&#xff0c;该技术讲座视频来自bilibili账号&#xff1a;MATLAB中国。 一、什么是卡尔曼滤波器 卡尔曼滤波器是一种优化估计算法&#xff0c;是一种设计最优状态观测器的方法&#xff0c;其功能为&#xff1a; 估算只能被间接测量的变量&#xff1b;通…

​漏电继电器JHOK-ZBLφ150mm 0.03-3A 0.2-2S导轨安装JOSEF约瑟

系列型号&#xff1a; JHOK-ZBL多档切换式漏电&#xff08;剩余&#xff09;继电器&#xff08;导轨&#xff09; JHOK-ZBL1多档切换式漏电&#xff08;剩余&#xff09;继电器 JHOK-ZBL2多档切换式漏电&#xff08;剩余&#xff09;继电器 JHOK-ZBM多档切换式漏电&#xff08;…