Flask 页面展示文件目录及文件,通过勾选复习框删除

news2025/1/12 0:47:06

(45条消息) flask 读取文件夹文件,展示在页面,可以通过勾选删除_U盘失踪了的博客-CSDN博客

基本实现

针对上面的功能再优化

项目结构 

app.py

import os
import shutil
from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

def generate_file_tree(path):
    root = {
        'name': os.path.basename(path),
        'type': 'directory',
        'children': []
    }
    for item in os.listdir(path):
        item_path = os.path.join(path, item)
        if os.path.isdir(item_path):
            child = generate_file_tree(item_path)
        else:
            child = {
                'name': item,
                'type': 'file'
            }
        root['children'].append(child)
    return root

def delete_selected_files_and_dirs(path, file_tree):
    selected_files = request.form.getlist('file-checkbox')
    for item in file_tree['children']:
        item_path = os.path.join(path, item['name'])
        if item['type'] == 'file':
            if item['name'] in selected_files:
                os.remove(item_path)
        elif item['type'] == 'directory':
            if item['name'] in selected_files:
                shutil.rmtree(item_path)
            else:
                delete_selected_files_and_dirs(item_path, item)

@app.route('/', methods=['GET', 'POST'])
def index():
    if not os.path.isdir('testfile'):
        os.makedirs('testfile')
    file_tree = generate_file_tree('testfile')
    if request.method == 'POST':
        delete_selected_files_and_dirs('testfile', file_tree)
        return redirect(url_for('index'))  # 重定向到相同的URL
    return render_template('index.html', file_tree=file_tree)

if __name__ == '__main__':
    app.run()

 templates / index.html

<!DOCTYPE html>
<html>
<head>
    <title>File Manager</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 10px;
        }

        h1 {
            text-align: center;
        }

        .file-tree {
            list-style: none;
            padding-left: 10px;
        }

        .file-tree .directory {
            margin-bottom: 10px;
        }

        .file-tree .file {
            list-style-type: none;
            margin-left: -25px;
        }

        .checkbox-label {
            display: inline-block;
            margin-right: 2px;
        }

        .delete-button {
            margin-top: 10px;
        }

        .file-tree li {
            position: relative;
            padding-left: 20px;
        }

        .file-tree li input[type="checkbox"] {
            position: absolute;
            right: 5; /* 将复选框放在右侧 */
            top: 0;
        }
    </style>
</head>
<body>
    <h1>File Manager</h1>
    <form method="POST" action="{{ url_for('index') }}">
        <ul class="file-tree">
            {% for item in file_tree['children'] %}
                {% if item['type'] == 'directory' %}
                    <li class="directory">
                        <label class="checkbox-label" for="{{ item['name'] }}"> {{ item['name'] }}</label>
                        <input type="checkbox" name="file-checkbox" value="{{ item['name'] }}" id="{{ item['name'] }}">
                        <ul>
                            {% for child in item['children'] %}
                                {% if child['type'] == 'file' %}
                                    <li class="file">
                                        <label class="checkbox-label" for="{{ child['name'] }}">{{ child['name'] }}</label>
                                        <input type="checkbox" name="file-checkbox" value="{{ child['name'] }}" id="{{ child['name'] }}">
                                    </li>
                                {% endif %}
                            {% endfor %}
                        </ul>
                    </li>
                {% endif %}
            {% endfor %}
        </ul>
        <button type="submit" class="delete-button">Delete Selected Files</button>
    </form>
</body>
</html>

效果图

 

优化一

目录折叠/展开文件

<!DOCTYPE html>
<html>
<head>
    <title>File Manager</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }

        h1 {
            text-align: center;
        }

        .file-tree {
            list-style: none;
            padding-left: 20px;
        }

        .file-tree .directory {
            margin-bottom: 5px;
        }

        .file-tree .file {
            list-style-type: none;
            margin-left: 20px;
        }

        .checkbox-label {
            display: flex;
            align-items: center;
        }

        .checkbox-label input[type="checkbox"] {
            margin-right: 5px;
        }

        .delete-button {
            margin-top: 10px;
        }

        .file-tree li {
            position: relative;
            padding-left: 20px;
        }

        .file-tree .directory > .file-tree {
            display: none;
        }

        .file-tree .directory.open > .file-tree {
            display: block;
        }

        .file-tree .directory > .checkbox-label::before {
            content: "+";
            display: inline-block;
            width: 10px;
            text-align: center;
            cursor: pointer;
        }

        .file-tree .directory.open > .checkbox-label::before {
            content: "-";
        }

        /* 新增的样式 */
        .file-tree .directory .checkbox-label {
            position: relative;
            left: -20px;
        }

        .file-tree .directory .checkbox-label input[type="checkbox"] {
            margin-right: 5px;
        }

        .file-tree .directory:not(.open) .checkbox-label input[type="checkbox"] {
            pointer-events: none;
        }
    </style>
    <script>
window.addEventListener('DOMContentLoaded', (event) => {
    const directories = document.querySelectorAll('.directory');
    directories.forEach(directory => {
        const checkboxLabel = directory.querySelector('.checkbox-label');
        const checkbox = directory.querySelector('input[type="checkbox"]');

        checkbox.addEventListener('click', (event) => {
            event.stopPropagation();
        });

        checkboxLabel.addEventListener('click', (event) => {
            if (!event.target.matches('input[type="checkbox"]')) {
                directory.classList.toggle('open');
                if (!directory.classList.contains('open')) {
                    checkbox.checked = false;
                }
            }
        });

        directory.addEventListener('click', () => {
            if (!directory.classList.contains('open')) {
                checkbox.checked = false;
            }
        });

        directory.addEventListener('transitionend', () => {
            if (directory.classList.contains('open')) {
                checkbox.disabled = false;
            } else {
                checkbox.disabled = true;
            }
        });
    });
});




    </script>
</head>
<body>
    <h1>File Manager</h1>
    <form method="POST" action="{{ url_for('index') }}">
        <ul class="file-tree">
            {% for item in file_tree['children'] %}
                {% if item['type'] == 'directory' %}
                    <li class="directory">
                        <label class="checkbox-label">
                            <input type="checkbox" name="file-checkbox" value="{{ item['name'] }}" id="{{ item['name'] }}">
                            {{ item['name'] }}
                        </label>
                        <ul class="file-tree">
                            {% for child in item['children'] %}
                                {% if child['type'] == 'file' %}
                                    <li class="file">
                                        <label class="checkbox-label">
                                            <input type="checkbox" name="file-checkbox" value="{{ child['name'] }}" id="{{ child['name'] }}">
                                            {{ child['name'] }}
                                        </label>
                                    </li>
                                {% endif %}
                            {% endfor %}
                        </ul>
                    </li>
                {% endif %}
            {% endfor %}
        </ul>
        <button type="submit" class="delete-button">Delete Selected Files</button>
    </form>
</body>
</html>

优化二

隐藏目录的复选框

<!DOCTYPE html>
<html>
<head>
    <title>File Manager</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }

        h1 {
            text-align: center;
        }

        .file-tree {
            list-style: none;
            padding-left: 20px;
        }

        .file-tree .directory {
            margin-bottom: 5px;
        }

        .file-tree .file {
            list-style-type: none;
            margin-left: 20px;
        }

        .delete-button {
            margin-top: 10px;
        }

        .file-tree li {
            position: relative;
            padding-left: 20px;
        }

        .file-tree .directory > .file-tree {
            display: none;
        }

        .file-tree .directory.open > .file-tree {
            display: block;
        }

        .file-tree .directory > .checkbox-label::before {
            content: "+";
            display: inline-block;
            width: 10px;
            text-align: center;
            cursor: pointer;
        }

        .file-tree .directory.open > .checkbox-label::before {
            content: "-";
        }
    </style>
    <script>
        window.addEventListener('DOMContentLoaded', (event) => {
            const directories = document.querySelectorAll('.directory');
            directories.forEach(directory => {
                const checkboxLabel = directory.querySelector('.checkbox-label');

                checkboxLabel.addEventListener('click', (event) => {
                    directory.classList.toggle('open');
                    event.stopPropagation();
                });

                directory.addEventListener('click', () => {
                    if (!directory.classList.contains('open')) {
                        directory.classList.add('open');
                    }
                });
            });
        });
    </script>
</head>
<body>
    <h1>File Manager</h1>
    <form method="POST" action="{{ url_for('index') }}">
        <ul class="file-tree">
            {% for item in file_tree['children'] %}
                {% if item['type'] == 'directory' %}
                    <li class="directory">
                        <label class="checkbox-label">
                            {{ item['name'] }}
                        </label>
                        <ul class="file-tree">
                            {% for child in item['children'] %}
                                {% if child['type'] == 'file' %}
                                    <li class="file">
                                        <label class="checkbox-label">
                                            <input type="checkbox" name="file-checkbox" value="{{ child['name'] }}" id="{{ child['name'] }}">
                                            {{ child['name'] }}
                                        </label>
                                    </li>
                                {% endif %}
                            {% endfor %}
                        </ul>
                    </li>
                {% endif %}
            {% endfor %}
        </ul>
        <button type="submit" class="delete-button">Delete Selected Files</button>
    </form>
</body>
</html>

 

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

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

相关文章

【蓝牙AVDTP A2DP协议】

蓝牙AVDTP A2DP 一.AVDTP1.1 AVDTP概念1.2 Source Sink整体框架1.3 AVDTP术语1.3.2 Stream1.3.2 SRC and Sink1.3.3 INT and ACP1.3.4 SEP&#xff1a; 1.4 AVDTP体系1.4.1 体系概括1.4.2 Transport Services 1.5 Signaling Procedures1.5.1 General Requirements1.5.2 Transac…

学习 C语言第一天 :C语言常见概念

1.C语言是什么&#xff1f; 那人和计算机是怎么交流的呢&#xff1f;使用计算机语言。 C语言就是众多计算机语言中的一种&#xff0c;当然C/Java/Go/Python都是计算机语言。 2.了解 C语言的历史和辉煌 初衷&#xff1a;C语言最初是作为 Unix系统开发工具而发明的。 历史过程&am…

uniapp uni.$emit()失效

1.业务场景 settle.vue页面引入bjs-settle.vue组件&#xff0c;bjs-settle.vue组件点击后在settle.vue中进行结算操作&#xff08;过程中有跳转&#xff09; 本来以为使用vue的this.$emit()就可以实现子组件回调父组件中的方法&#xff0c;但是发现没用。 然后看到uniapp中需…

Linux性能与统计命令

目录&#xff1a; linux常用命令之性能统计linux常用统计命令linux进程与线程Linux性能统计 1.linux常用命令之性能统计 为什么要学习性能统计&#xff1f; 性能统计是衡量系统性能的重要手段&#xff0c;通过对系统各项指标的监控和分析&#xff0c;可以及时发现系统瓶颈和…

山西电力市场日前价格预测【2023-07-24】

日前价格预测 预测明日&#xff08;2023-07-24&#xff09;山西电力市场全天平均日前电价为338.25元/MWh。其中&#xff0c;最高日前电价为377.59元/MWh&#xff0c;预计出现在20: 30。最低日前电价为283.56元/MWh&#xff0c;预计出现在13: 30。 价差方向预测 1&#xff1a;实…

Linux系统初装后的配置

目录 1、学习环境关闭SElinux 2、关闭防火墙 3、添加用户 4、使用sudo进行权限管理 5、修改ssh服务的默认配置 6、修改网卡参数 环境&#xff1a;centOS7 1、学习环境关闭SElinux 临时关闭 &#xff1a;setenforce 0;查看状态&#xff1a;getenforce;临时开启&#xff…

uniapp 小程序 查看评价

查看评价效果图&#xff1a; 评分组件在上一篇文章&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; <template><view class"view-comments"><view class"evaluate-box"><view class"ti…

C++ | set与map的用法指南

前言 前面我们学习了vector、list等容器&#xff0c;其实他们都属于序列式容器&#xff0c;因为其底层为线性结构&#xff1b;今天我们学习使用的set与map是属于关联式容器&#xff0c;关联式容器更注重于数据检索访问的效率&#xff1b;本文所有的资料均查阅于文档&#xff0c…

Python实战项目——旅游数据分析(四)

由于有之前的项目&#xff0c;所以今天我们直接开始&#xff0c;不做需求分析&#xff0c;还不会需求分析的可以看我之前的文章。Python实战项目——用户消费行为数据分析&#xff08;三&#xff09; 导入库 import numpy as np import pandas as pd import matplotlib.pyplo…

Sentinel授权规则与规则持久化

&#x1f333;&#x1f333;&#x1f333;&#x1f333;&#x1f333;&#x1f333;&#x1f333; 学习授权规则前&#xff0c;先想想SpringCloud Gateway的黑白名单&#xff0c;请求过网关&#xff0c;gateway会去鉴权。但如果有人把微服务信息泄露出去了呢&#xff1f;此时微…

输出函数print

print("hello world") # 可以输出数字 print(1111) print(2222) # 可以输出字符串 print(helloworld) print("helloworld") # 可以输出运算符的表达式 print(56) # 将数据输出文件中&#xff0c;注意点&#xff1a;1.所指定的盘符存在&#xff0c;2.使…

「苹果安卓」手机搜狗输入法怎么调整字体大小及键盘高度?

手机搜狗输入法怎么调整字体大小及键盘高度&#xff1f; 1、在手机上准备输入文字&#xff0c;调起使用的搜狗输入法手机键盘&#xff1b; 2、点击搜狗输入法键盘左侧的图标&#xff0c;进入更多功能管理&#xff1b; 3、在搜狗输入法更多功能管理内找到定制工具栏&#xff0c…

uni-app中全局设置页面背景颜色

在uni-app中设置背景颜色&#xff0c;想象中应该很简单&#xff0c;其实里面也还是有点小坑的&#xff0c;我们来一起看一下。 方法一&#xff1a;pages.json globalStyle 中设置 backgroundColor 结果&#xff1a;未生效 猜测可能是颜色不能用别名&#xff0c;换十六进制试一…

讯为RK3568开发板入门之-tftpnfs的配置

基础条件 VMware虚拟机 Ubuntu18.04 【网络配置陈桥接模式】 RK3568开发板【我是用讯为的RK3568】 网线连接路由器或者和电脑直连 配置TFTP和NFS的作用 使用tftp和nfs网络挂载可以很方便的进行软件的调试&#xff0c;挂载成功后只要把Ubuntu下编译好的文件程序放到挂载的目录…

有名管道(FIFO)的学习笔记

文章目录 有名管道介绍有名管道的使用创建 注意事项 有名管道介绍 有名管道的使用 创建 命令&#xff0c; mkfifo name函数&#xff0c;int mkfifo(const char *pathname, mode_t mode); 设置错误号&#xff1b; 向管道中写数据&#x1f447;&#xff1a; 从管道读数据&am…

数据库新闻速递 SingleStore Kai for MongoDB有以下6个关键特性, MONGODB 也疯狂

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到3群&#xff08;共…

Hive查询性能优化——物化视图(materialized view)

1. 背景&#xff1a; 在一次大表查询中&#xff0c;查询速度非常慢,插叙时间以分钟为单位&#xff0c;而生产需求要达到10s以内。造成这个问题的原因有多种&#xff0c;性能调优的方式也有多种&#xff0c;这里记录一下其中一种方案&#xff0c;采用物化视图&#xff08;Mater…

[JAVAee]synchronized关键字

目录 1.synchronized的特性 ①互斥性 ②可重入性 2.synchronized的使用示例 ①修饰普通方法 ②修饰静态方法 ③修饰代码块 1.synchronized的特性 ①互斥性 互斥性,就像是给门上锁了一样. 当A线程使用了被synchronized修饰的代码块并对其上锁,其他线程(B线程,C线程)想要使…

从零开始学习自动驾驶路径规划-环境配置

从零开始学习自动驾驶路径规划-环境配置 前面&#xff0c;每个人遇到的问题不一样&#xff0c;这里记录了配置步骤和目前遇到的问题&#xff0c;会持续更新报错解决方法。配置时有报错请认真看报错经验 环境配置步骤&#xff08;18.04和20.04都可以&#xff0c;有些问题没遇到…

流媒体视频融合平台EasyCVR更新版本后,首页无法打开的原因排查与解决

EasyCVR视频融合平台基于云边端一体化架构&#xff0c;可支持多协议、多类型设备接入&#xff0c;包括&#xff1a;NVR、IPC、视频编码器、无人机、车载设备、智能手持终端、移动执法仪等。平台具有强大的数据接入、处理及分发能力&#xff0c;可在复杂的网络环境中&#xff0c…