【python】flask搭建一个上传网站css+js+flask(1)

本文介绍了一个基于Flask框架的文件上传应用,包括图片缩略图生成、文件重命名和类型检查等功能。该应用使用Python和PIL库处理图片,并提供RESTful API进行文件上传、删除和获取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考代码: https://github.com/blueimp/jQuery-File-Upload/

代码逻辑由app.py决定,具体功能见我加上的注释:
在这里插入图片描述
app.py

#!flask/bin/python

# Author: Ngo Duy Khanh
# Email: ngokhanhit@gmail.com
# Git repository: https://github.com/ngoduykhanh/flask-file-uploader
# This work based on jQuery-File-Upload which can be found at https://github.com/blueimp/jQuery-File-Upload/

import os
import PIL
from PIL import Image
import simplejson
import traceback

from flask import Flask, request, render_template, redirect, url_for, send_from_directory
from flask_bootstrap import Bootstrap
from werkzeug.utils import secure_filename

from lib.upload_file import uploadfile


app = Flask(__name__)   # 使用flask框架,绑定
app.config['SECRET_KEY'] = 'hard to guess string'  # 设置秘钥,路径,最大图片大小等等
app.config['UPLOAD_FOLDER'] = 'data/'
app.config['THUMBNAIL_FOLDER'] = 'data/thumbnail/'
app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024

ALLOWED_EXTENSIONS = set(['txt', 'gif', 'png', 'jpg', 'jpeg', 'bmp', 'rar', 'zip', '7zip', 'doc', 'docx'])
IGNORED_FILES = set(['.gitignore'])

bootstrap = Bootstrap(app)

'''
检查类型
'''
def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS  # 检查类型是否包含在列表里

'''
针对重名情况进行处理
'''
def gen_file_name(filename):
    """
    If file was exist already, rename it and return a new name
    """

    i = 1
    while os.path.exists(os.path.join(app.config['UPLOAD_FOLDER'], filename)):
        name, extension = os.path.splitext(filename)
        filename = '%s_%s%s' % (name, str(i), extension)
        i += 1

    return filename

'''
建立缩略图
'''
def create_thumbnail(image):
    try:
        base_width = 80 # 宽度基线
        img = Image.open(os.path.join(app.config['UPLOAD_FOLDER'], image)) # 载入图片
        w_percent = (base_width / float(img.size[0])) # 宽度和像素比
        h_size = int((float(img.size[1]) * float(w_percent))) # 等比缩放
        img = img.resize((base_width, h_size), PIL.Image.ANTIALIAS) # 修改图片大小
        img.save(os.path.join(app.config['THUMBNAIL_FOLDER'], image)) # 保存图片到本地

        return True

    except:
        print(traceback.format_exc()) # 异常处理,打印栈路径
        return False


# 访问路径修改为http://127.0.0.1:5000/upload 时调用upload
@app.route("/upload", methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        files = request.files['file']

        if files:
            filename = secure_filename(files.filename)  # 防止黑客攻击,去除不安全的命名,安全命名
            filename = gen_file_name(filename)  # 生产新命名
            mime_type = files.content_type  #  保存媒体类型 图片:image/jpeg

            if not allowed_file(files.filename):
                result = uploadfile(name=filename, type=mime_type, size=0, not_allowed_msg="File type not allowed")

            else:
                # save file to disk
                uploaded_file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)  # 路径地址加上文件名称
                files.save(uploaded_file_path)  # 文件保存到上传路径

                # create thumbnail after saving
                if mime_type.startswith('image'):
                    create_thumbnail(filename)  # 图片类型,创建缩略图

                # get file size after saving
                size = os.path.getsize(uploaded_file_path)  # 保存后,读取本地文件获取文件大小

                # return json for js call back
                result = uploadfile(name=filename, type=mime_type, size=size)  # 上传文件
                print(uploadfile(name=filename, type=mime_type, size=size))

            return simplejson.dumps({"files": [result.get_file()]})

    if request.method == 'GET':
        print("get")
        # get all file in ./data directory
        files = [f for f in os.listdir(app.config['UPLOAD_FOLDER']) if os.path.isfile(os.path.join(app.config['UPLOAD_FOLDER'],f)) and f not in IGNORED_FILES ]

        file_display = []

        for f in files:
            size = os.path.getsize(os.path.join(app.config['UPLOAD_FOLDER'], f))
            file_saved = uploadfile(name=f, size=size)
            file_display.append(file_saved.get_file())

        return simplejson.dumps({"files": file_display})

    return redirect(url_for('index'))


@app.route("/delete/<string:filename>", methods=['DELETE'])
def delete(filename):
    file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
    file_thumb_path = os.path.join(app.config['THUMBNAIL_FOLDER'], filename)

    if os.path.exists(file_path):
        try:
            os.remove(file_path)

            if os.path.exists(file_thumb_path):
                os.remove(file_thumb_path)

            return simplejson.dumps({filename: 'True'})
        except:
            return simplejson.dumps({filename: 'False'})


# serve static files
@app.route("/thumbnail/<string:filename>", methods=['GET'])
def get_thumbnail(filename):
    return send_from_directory(app.config['THUMBNAIL_FOLDER'], filename=filename)


@app.route("/data/<string:filename>", methods=['GET'])
def get_file(filename):
    return send_from_directory(os.path.join(app.config['UPLOAD_FOLDER']), filename=filename)


@app.route('/', methods=['GET', 'POST'])
def index():
    return render_template('index.html')


if __name__ == '__main__':
    app.run(debug=True, port=9191)

<think>好的,我现在需要帮助用户了解如何使用Flask、HTML、JavaScript、CSS和MySQL进行Web开发的整体架构和实现思路。首先,我得理清各个技术在这些组合中的作用,以及它们如何协同工作。 用户提到了Flask、HTML、JavaScript、CSS和MySQL,这些都是Web开发中的常见技术。我需要先明确每个部分的职责。Flask作为后端框架,负责处理HTTP请求,与数据库交互,生成动态内容。HTML、CSS和JavaScript是前端的三剑客,分别负责结构、样式和交互。MySQL则是数据库,存储数据。接下来,我需要组织这些内容,形成一个清晰的架构。 首先,可能需要从项目结构开始。典型的Flask项目会有应用工厂模式,包含不同的目录如static、templates、models、routes等。需要解释这些目录的作用,比如static存放CSSJS文件,templates存放HTML模板。然后,数据库部分,使用Flask-SQLAlchemy或Flask-MySQLdb来连接MySQL,定义模型类。这里可能需要提到ORM的好处,比如避免直接写SQL,提高开发效率。 然后是路由和视图函数,Flask通过路由将URL映射到对应的处理函数,这些函数从数据库获取数据,渲染模板,返回给客户端。模板引擎Jinja2的使用,如何将动态数据插入HTML中。前端部分,CSS负责样式,JavaScript处理交互,比如AJAX请求,与后端API通信。 接下来需要考虑数据流:用户发起请求,路由处理,视图函数查询数据库,返回数据到模板,生成HTML响应,浏览器渲染,JavaScript增强交互。同时,可能需要提到表单处理,用户认证,会话管理,这些是Web应用常见的功能,Flask有相应的扩展如Flask-WTF、Flask-Login。 另外,安全性方面需要考虑,比如防止SQL注入,XSS攻击,CSRF保护。Flask-WTF可以帮助表单的CSRF保护,使用参数化查询避免SQL注入。数据库迁移可能也是一个点,使用Flask-Migrate来管理数据库变更。 最后,部署方面可能需要简要提及,比如使用Nginx和Gunicorn部署Flask应用,MySQL的配置优化等。不过用户可能更关注开发阶段的架构,部署可能不是重点。 现在需要检查是否有遗漏的部分,比如RESTful API的设计,如果前端需要与后端通过AJAX交互,可能需要设计API端点。或者前后端分离的情况,但用户的问题里提到了HTML、JavaScript,可能更偏向于传统的服务端渲染加上一些前端交互,而非完全前后端分离。 还需要考虑如何组织静态文件,如何在模板中引入CSSJS,如何处理静态资源缓存。可能还要提到使用CDN来加速静态资源的加载,但属于优化部分,基础架构中可能不需要深入。 对于数据库部分,需要说明如何配置MySQL连接,创建表结构,使用Flask的扩展进行数据库操作。例如,使用Flask-SQLAlchemy定义模型,执行查询,插入数据等操作。 在代码示例方面,可能需要给出一个简单的Flask应用结构,比如初始化代码,配置数据库连接,定义模型类,编写路由和视图函数,以及一个简单的HTML模板示例,展示如何集成CSS和JavaScript。 同时,要确保按照用户的要求,行内数学表达式用$...$,独立公式用$$...$$,但这个问题中可能数学内容较少,需要看是否有需要的地方。例如,在讨论算法或性能分析时可能需要,但当前问题可能不涉及太多数学公式,所以可能不需要特别处理。 最后,生成相关问题需要考虑用户可能的后续疑问,比如如何实现用户认证,如何处理表单验证,如何进行数据库迁移,如何优化性能,如何部署等。需要确保问题与当前主题相关,帮助用户进一步学习。 总结整个思考过程,需要分步骤解释架构,每个技术的作用,数据流动,代码结构示例,以及安全性和部署的注意事项。同时保持回答结构清晰,符合用户要求的系统级指令和格式规范。</think>### 使用Flask+HTML+JavaScript+CSS+MySQL的Web开发架构思路 #### 1. 技术栈分工 - **Flask**:后端框架,处理路由请求、业务逻辑、数据库交互[^1] - **HTML**:页面结构定义,通过Jinja2模板引擎实现动态内容渲染 - **CSS**:界面样式设计,支持响应式布局 - **JavaScript**:前端交互逻辑,可配合AJAX实现异步通信 - **MySQL**:关系型数据库,存储结构化数据 #### 2. 典型项目结构 ```bash /project-root ├── app.py # Flask主程序入口 ├── config.py # 配置文件 ├── requirements.txt ├── /static # 静态资源 │ ├── css/ │ ├── js/ │ └── images/ ├── /templates # HTML模板 │ └── index.html ├── /models # 数据模型定义 │ └── user.py └── /routes # 路由模块 └── auth.py ``` #### 3. 核心实现步骤 **3.1 数据库配置** ```python # app.py from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://user:password@localhost/dbname' db = SQLAlchemy(app) # 定义数据模型 class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True) email = db.Column(db.String(120)) ``` **3.2 路由与视图** ```python # routes/auth.py from flask import Blueprint, render_template auth_bp = Blueprint('auth', __name__) @auth_bp.route('/login') def login(): return render_template('login.html') ``` **3.3 模板渲染** ```html <!-- templates/login.html --> <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="/static/css/style.css"> </head> <body> <form id="login-form"> <input type="text" name="username"> <button onclick="submitForm()">登录</button> </form> <script src="/static/js/app.js"></script> </body> </html> ``` **3.4 前后端交互** ```javascript // static/js/app.js function submitForm() { fetch('/api/login', { method: 'POST', body: JSON.stringify({username: 'test'}) }).then(response => response.json()) } ``` #### 4. 关键技术点 - **ORM操作**:使用SQLAlchemy执行$SELECT * FROM users WHERE id=1$等价操作 - **会话管理**:通过Flask-Login实现用户状态保持 - **表单验证**:使用WTForms处理输入验证 - **API设计**:RESTful风格接口设计,返回JSON格式数据 #### 5. 安全注意事项 1. SQL注入防护:使用ORM或参数化查询 2. XSS防护:模板自动转义特殊字符 3. CSRF防护:启用Flask-WTF扩展 4. 密码存储:使用bcrypt哈希加密
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值