You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flask项目的mod1中导入复用mod2的文件上传功能?

问题:Flask主模块mod1复用mod2的文件上传功能无效果

背景

目标是在主模块mod1.py中实现文件上传,文件保存至/static/img/目录,但尝试后无文件保存。希望从同根目录的mod2.py导入复用上传功能,已添加空__init__.py,未使用Django。目前无报错但文件未保存,求方向判断及具体解决建议。

项目结构

root/
    __init__.py
    mod1.py
    mod2.py

mod1 可用代码

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

app = Flask(__name__)
app.config["DEBUG"] = True

comments = []

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "GET":
        return render_template("main_page.html", comments=comments)

    comments.append(request.form["contents"])
    return redirect(url_for('index'))

mod2 可用代码

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

from werkzeug.utils import secure_filename
from flask_uploads import IMAGES, UploadSet, configure_uploads

UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'docx'}

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

photos = UploadSet("photos", IMAGES)
app.config["UPLOADED_PHOTOS_DEST"] = "static/img"
app.config["SECRET_KEY"] = os.urandom(24)
configure_uploads(app, photos)

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST' and 'photo' in request.files:
        photos.save(request.files['photo'])
        flash("Photo saved successfully.")
        return render_template('upload.html')
    return render_template('upload.html')

from flask import send_from_directory

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

from werkzeug.middleware.shared_data import SharedDataMiddleware
app.add_url_rule('/uploads/<filename>', 'uploaded_file', build_only=True)
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
    '/uploads':  app.config['UPLOAD_FOLDER']
})

mod1 中的尝试代码

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

from werkzeug.utils import secure_filename
from flask import Request
from flask_uploads import IMAGES, UploadSet, configure_uploads

from mod1 import getPhotos
from mod1 import upload

UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'docx'}

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

photos = getPhotos()

app.config["UPLOADED_PHOTOS_DEST"] = "static/img"
app.config["SECRET_KEY"] = os.urandom(24)
configure_uploads(app, photos)

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

upload()

"""
#as a function
@app.route('/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST' and 'photo' in request.files:
        photos.save(request.files['photo'])
        flash("Photo saved successfully.")
        return render_template('upload.html')
    return render_template('upload.html')
"""
from flask import send_from_directory
@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

from werkzeug.middleware.shared_data import SharedDataMiddleware
app.add_url_rule('/uploads/<filename>', 'uploaded_file', build_only=True)
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
    '/uploads':  app.config['UPLOAD_FOLDER']
})

问题分析与解决建议

方向判断

你的方向是对的——复用已有模块的上传功能是合理的,但尝试代码中存在几个关键错误导致功能失效。

具体错误点

  1. 错误的导入路径:尝试代码中写了from mod1 import getPhotos, upload,但这两个对象是在mod2里定义的,应该改为from mod2 import photos, upload。
  2. 重复创建Flask实例:mod1本身已经有一个app实例,尝试代码里又重新创建了一个新的app,导致配置和路由都绑定到了错误的实例上,运行时实际使用的是mod1原来的app,而不是你配置了上传功能的新app。
  3. 直接调用upload()函数:upload()是一个路由视图函数,需要由Flask的请求调度来触发,直接调用它不会处理请求,也不会绑定路由。
  4. 路由冲突:mod1原有@app.route("/")和上传功能的/路由冲突,需要修改上传路由的路径,比如改为/upload。

修正后的mod1代码

import os
from flask import Flask, redirect, render_template, request, url_for
from mod2 import photos, upload  # 正确导入mod2中的对象

app = Flask(__name__)
app.config["DEBUG"] = True
app.config["UPLOADED_PHOTOS_DEST"] = "static/img"
app.config["SECRET_KEY"] = os.urandom(24)
app.config['UPLOAD_FOLDER'] = 'uploads'

# 配置上传集合到当前app实例
from flask_uploads import configure_uploads
configure_uploads(app, photos)

comments = []

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "GET":
        return render_template("main_page.html", comments=comments)

    comments.append(request.form["contents"])
    return redirect(url_for('index'))

# 注册mod2中的上传路由,修改路径避免冲突
app.add_url_rule('/upload', view_func=upload, methods=['GET', 'POST'])

# 复用mod2中的文件访问路由
from mod2 import uploaded_file
app.add_url_rule('/uploads/<filename>', view_func=uploaded_file)

# 添加共享数据中间件
from werkzeug.middleware.shared_data import SharedDataMiddleware
app.add_url_rule('/uploads/<filename>', 'uploaded_file', build_only=True)
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
    '/uploads':  app.config['UPLOAD_FOLDER']
})

额外注意事项

  • 确保static/img目录存在,Flask不会自动创建目录,运行前手动创建:mkdir -p static/img。
  • 上传表单的enctype必须设为multipart/form-data,否则文件无法正确传递:
    <!-- 在upload.html中 -->
    <form method="POST" enctype="multipart/form-data">
        <input type="file" name="photo">
        <button type="submit">上传</button>
    </form>
    
  • 检查mod2中的UPLOAD_FOLDER和UPLOADED_PHOTOS_DEST路径是否是相对当前项目根目录的,避免路径错误。

内容的提问来源于stack exchange,提问作者Kamus Suwanto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 09:45:48