Skip to content

文件上传

说明

提供本地文件上传功能,支持图片和通用文件上传,内置扩展名白名单校验。服务层位于 application/upload/services.py,视图层位于 application/upload/views.py

功能概述

文件上传模块提供统一的文件上传接口 upload_file,支持图片、文档、压缩包等各类文件,通过扩展名列表控制允许上传的格式。

POST /upload/uploadFile  —— 统一文件上传入口

配置项

config/env.py 中配置上传相关参数:

python
# 上传文件存储根目录
DJANGO_UPLOAD_DIR = os.getenv('DJANGO_UPLOAD_DIR', os.path.join(DJANGO_ROOT_PATH, '/public/uploads'))

# 临时文件路径
DJANGO_TEMP_PATH = DJANGO_UPLOAD_DIR + '/temp'

# 文件访问域名
DJANGO_FILE_URL = os.getenv('DJANGO_FILE_URL', 'http://file.django.elevue')

温馨提示

DJANGO_FILE_URL 用于拼接完整的文件访问 URL,生产环境需配置为实际的文件服务域名或 Nginx 代理地址。

文件命名规则

上传文件自动重命名,格式为:年月日时分秒 + 5位随机数 + 扩展名

python
# application/upload/services.py
timestamp = time.strftime('%Y%m%d%H%M%S')
random_num = f'{random.randint(0, 99999):05d}'
generated_name = f"{timestamp}{random_num}{file_ext_with_dot}"

文件按日期分目录存储:{UPLOAD_DIR}/temp/{YYYYMMDD}/{文件名}

接口调用

上传文件

POST /upload/uploadFile
Content-Type: multipart/form-data
Authorization: Bearer <token>
参数: file(文件字段)

响应示例:

json
{
    "code": 0,
    "msg": "上传成功",
    "data": {
        "originalName": "photo.jpg",
        "fileExtension": "jpg",
        "fileType": "image/jpeg",
        "fileSize": 306995,
        "fileName": "2025030614302512345.jpg",
        "filePath": "/temp/20250306/2025030614302512345.jpg",
        "fileUrl": "http://file.django.elevue/temp/20250306/2025030614302512345.jpg"
    },
    "ok": true
}

安全机制

扩展名白名单

文件上传服务对扩展名进行白名单校验,支持的格式包括:

图片:.jpeg, .jpg, .png, .gif, .bmp
文档:.doc, .docx, .xls, .xlsx, .ppt, .pptx, .pdf, .txt

文件类型校验

通过 mimetypes 模块推断文件的 MIME 类型,确保文件内容与扩展名一致。

路径安全

文件存储在临时目录中,业务提交时通过 save_file() 迁移到正式目录,避免路径遍历风险。

临时文件迁移

上传的文件首先存储在 temp 目录,业务数据提交时调用 save_file() 迁移到正式目录:

python
# utils/common.py
def save_file(url, directory):
    """将临时文件迁移到正式存储目录"""
    if url.find(DJANGO_FILE_URL) != -1:
        if url.find("/temp") != -1:
            # 构建目标目录路径
            path = DJANGO_UPLOAD_DIR + "/" + directory + "/" + time.strftime('%Y%m%d')
            mkdir(path)
            # 移动文件
            old_path = url.replace(DJANGO_FILE_URL, DJANGO_UPLOAD_DIR)
            new_path = DJANGO_UPLOAD_DIR + "/" + directory + old_path.replace(DJANGO_TEMP_PATH, "")
            os.rename(old_path, new_path)
            return new_path.replace(DJANGO_UPLOAD_DIR, "")

文件 URL 拼接

get_file_url() 函数将相对路径拼接为完整的文件访问 URL:

python
# utils/common.py
def get_file_url(path):
    if not path:
        return None
    return DJANGO_FILE_URL + path

前端集成

前端使用 Upload 组件上传,上传成功后将返回的 fileUrl 存入业务字段。详见 文件上传联调 章节。

总结

文件上传模块通过扩展名白名单、MIME 类型校验、临时目录隔离等安全机制,确保上传功能的安全性。文件自动重命名并按日期分目录存储,避免文件名冲突和信息泄露。统一的 uploadFile 接口同时支持图片和各类文件上传。

小蚂蚁云团队 · 提供技术支持