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

(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>

 

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

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

相关文章

服务器数据恢复-Windows服务器RAID5数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器挂载三台IBM某型号存储设备&#xff0c;共64块SAS硬盘&#xff0c;组建RAID5磁盘阵列&#xff1b; 服务器操作系统&#xff1a;Windows Server&#xff1b;文件系统&#xff1a;NTFS。 服务器故障&#xff1a; 一台存储中的一块硬盘离…

android app控制ros机器人一

android开发app&#xff0c;进而通过控制ros机器人&#xff0c;记录开发过程 查阅资料&#xff1a; rosjava使用较多&#xff0c;已经开发好的app也有开源的案例 rosjava GitHub https://github.com/ros-autom/RobotCA https://github.com/ROS-Mobile/ROS-Mobile-Android…

Godot 4 着色器 - Shader调试

我之前用OpenCV进行图像相关处理&#xff0c;觉得已经很不错&#xff0c;结合GDI可以实现流畅的动画效果 直到近来用Shader后才发现&#xff0c;着色器更上一层楼&#xff0c;原来这是入了GPU的坑 Shader编程限制很多&#xff0c;各种不支持&#xff0c;看在它性能不错功能炫…

vue 封装一个鼠标拖动选择时间段功能

<template><div class"timeRange"><div class"calendar"><table><thead><tr><th rowspan"6" class"weekRow"><b>周/时间</b></th><th colspan"24"><…

vue中的数据代理

vue数据代理 Vue实现数据代理的核心----Object.defineProperty(); 数据代理 数据代理的定义是&#xff1a;一个对象操作(读\写)另一个对象中的属性和方法。 // 数据代理&#xff1a;通过一个对象代理对另一个对象中属性的操作&#xff08;读/写&#xff09;let obj { x: 100…

vue element ui web端引入百度地图,并获取经纬度

最近接到一个新需要&#xff0c;要求如下&#xff1a; 当我点击选择地址时&#xff0c;弹出百度地图&#xff0c; 效果如下图&#xff1a; 实现方法&#xff1a; 1、首先要在百度地图开放平台去申请一个账号和key 2、申请好之后&#xff0c;在项目的index.html中引入 3、…

Error: Please select Android SDK解决方案(仅供参考)

一、问题描述 今天开始正式接触项目的工作内容&#xff0c;然后从组里的代码仓库里git clone了一份Android Studio项目下来。下好了以后我使用Android Studio打开这个项目&#xff0c;但在尝试编译运行的时候遇到了很多错误。例如&#xff0c;开发环境界面上边用于编译的小锤子…

五,Eureka 第五章

5.3.2 修改pom添加依赖 <dependencies><!--公共部门--><dependency><groupId>cn.bdqn</groupId><artifactId>springcloud-api-commons</artifactId><version>${project.version}</version></dependency><!--e…

Python电商爬虫保姆级入门教程(纯新手向)

图灵Python课堂 长沙图灵教育于2001年开始进入教育行业&#xff0c;立足泛IT类职业教育&#xff0c;以打造高新技术人才为宗旨&#xff0c;专注于提供多层次、个性化的职业技能培训课程&#xff0c;为各行业培养技术开发、应用和管理等岗位的中高端人才&#xff0c;致力于成为…

Python学习笔记-Django框架基础,APP,数据模型,后台管理,路由

一、Django框架简介 Django框架是Python的常用web框架&#xff0c;遵循 MVC 设计模式的框架&#xff0c;采用了MTV的框架模式&#xff0c;即模型M&#xff0c;视图V和模版T。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的&#xff0c;即是CMS&…

双虚拟机实现数据库自动备份

FTP的使用&#xff1a; 1.安装FTP 1、检测系统有没有安装ftp&#xff0c;执行命令&#xff1a; rpm -qa | grep ftp若存在用rpm命令移除后再行安装&#xff0c;执行命令&#xff1a; rpm -e vsftpd-3.0.2-9.e17.x86_642、如果没有安装&#xff0c;则在线安装ftp&#xff0c…

Vue2基础八、插槽

零、文章目录 Vue2基础八、插槽 1、插槽 &#xff08;1&#xff09;默认插槽 作用&#xff1a;让组件内部的一些 结构 支持 自定义需求: 将需要多次显示的对话框, 封装成一个组件问题&#xff1a;组件的内容部分&#xff0c;不希望写死&#xff0c;希望能使用的时候自定义。…

关于anki的一些思考

文章目录 通常情况下选择什么模板制卡&#xff1f;一张填空卡片的填空数量到底要多少才合适&#xff1f; 通常情况下选择什么模板制卡&#xff1f; 通常情况是指知识是以一段文字的形式呈现&#xff0c;而不是这些&#xff1a;单词、选择题、成语等&#xff08;这些都可以定制…

openlayers根据下拉框选项在地图上显示图标

这里是关于一个根据下拉框的选项在地图上显示图标的需求&#xff0c;用的是vueopenlayers 显示效果大概是这样&#xff1a; 选中选项之后会跳转到所点击的城市&#xff0c;并且在地图上显示图标温度&#xff0c;这一块UI没设计我就大概先弄了一下&#xff0c;比较丑。。 首先…

【C++】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动

[导读]本系列博文内容链接如下&#xff1a; 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动 在【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值一文中介绍了如何利用…

Java使用FFmpeg实现mp4转m3u8

Java使用FFmpeg实现mp4转m3u8 前言FFmpegM3U8 一、需求及思路分析二、安装FFmpeg1.windows下安装FFmpeg2.linux下安装FFmpegUbuntuCentOS 三、代码实现1.引入依赖2.修改配置文件3.工具类4.Controlle调用5.Url转换MultipartFile的工具类 四、播放测试1.html2.nginx配置3.效果展示…

uniapp实现带参数二维码

view <view class"canvas"><!-- 二维码插件 width height设置宽高 --><canvas canvas-id"qrcode" :style"{width: ${qrcodeSize}px, height: ${qrcodeSize}px}" /></view> script import uQRCode from /utils/uqrcod…

LeetCode.189(轮转数组)

对于轮转数组这个题&#xff0c;文章一共提供三种思路&#xff0c;对于每种思路均提供其对应代码的时间、空间复杂度。 目录 1. 创建变量来保存最后一个数&#xff0c;并将其余数组向前挪动一位 &#xff1a; 1.1 原理解析&#xff1a; 1.2 代码实现&#xff1a; 2.创建一个…

Ftp和UDP的区别之如何加速文件传输

FTP&#xff08;文件传输协议&#xff09;是一种传输大文件的老方法&#xff0c;它的速度慢&#xff0c;而且容易受到网络环境的影响。在当今这个文件越来越大&#xff0c;项目交付时间越来越紧&#xff0c;工作分布在全球各地的时代&#xff0c;有没有办法让 FTP 加速呢&#…

重学C++系列之const与static关键字分析

前言 本篇幅讲解关键字const与static&#xff0c;主要围绕在类的范围内叙述&#xff0c;包括作用和使用场景等。 一、const与static的作用 1、const修饰的成员变量&#xff0c;成员变量初始化后不能再修改。 2、const修饰的成员函数&#xff0c;成员函数不可以修改成员变量&am…