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

Flask中request.files无法获取文件部分,请求排查上传失败原因

解决文件上传时触发"No file part"的问题

我来帮你排查这个文件上传失败的问题,核心问题出在HTML表单的配置上,另外Python代码里也有几个需要调整的地方,一步步来看:

1. HTML表单的enctype属性位置错误

你现在把enctype="multipart/form-data"写在了<input type="file">标签里,但这个属性必须放在<form>标签上——浏览器只有识别到form标签的这个属性,才会正确编码并发送文件数据。如果form没有配置这个属性,Flask的request.files就无法获取到上传的文件,自然会触发"No file part"的提示。

修改后的HTML代码:

{% extends "layout.html" %} {% block title %} Picture {% endblock %} {% block main %} 
<form action="/picture" method="post" enctype="multipart/form-data"> 
  <div> 
    <p>Profile picture (32mb max).</p> 
    <input type="file" id="picture" name="picture"> 
    <input type="submit" value="Upload"> 
  </div> 
</form> 
{% endblock %}

2. Python代码里的几个潜在问题

除了HTML的问题,你的Python代码还有几个需要修正的点,否则即使表单正确了,上传也可能失败:

问题A:错误地提前读取了文件内容

你调用了file = request.files["picture"].read(),这会把文件内容一次性读进内存,但之后再访问file.filename就会失效——因为read()操作会把FileStorage对象的指针移到文件末尾,此时变量file已经变成了字节流,不再是原来的FileStorage对象,自然没有filename属性。

应该先获取文件名和验证,再处理文件保存。

问题B:文件保存路径可能不正确

os.path.join("/static", filename)是绝对路径,在不同环境下可能找不到对应的目录,建议用Flask应用的根目录来拼接相对路径,避免环境差异导致的路径错误。

问题C:返回值错误

最后return print(filename)只会在控制台打印文件名,用户浏览器会得到一个空响应,应该重定向到某个页面(比如个人资料页)或者渲染模板,给用户明确的反馈。

修改后的Python代码示例:

import sqlite3
import traceback
import sys
import os
from flask import Blueprint, render_template, redirect, session, request, flash
from application import profileName, uploadPicture, profilePicture, allowed_file
from werkzeug.utils import secure_filename

# Set Blueprints
picture = Blueprint('picture', __name__,)

@picture.route("/picture", methods=["GET", "POST"])
def pictureFunction():
    # 先检查用户是否登录(根据你的session逻辑调整)
    if "user_id" not in session:
        flash("Please log in first")
        return redirect("/login")
        
    if request.method == "POST":
        # check if the post request has the file part
        if "picture" not in request.files:
            flash("No file part")
            return redirect("/picture")
            
        file = request.files["picture"]
        # if user does not select file, browser also submit a empty part without filename
        if file.filename == "":
            flash("No selected file")
            return redirect("/picture")
            
        # Check if all conditions are satisfied
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            # 用Flask蓝图的根目录拼接静态文件路径,避免绝对路径问题
            upload_path = os.path.join(picture.root_path, "static", filename)
            file.save(upload_path)
            # 这里可以调用你的uploadPicture函数把文件名存到数据库
            # uploadPicture(session["user_id"], filename)
            flash("Profile picture uploaded successfully!")
            return redirect("/profile") # 重定向到个人资料页或者其他页面
    # GET请求时渲染上传页面
    return render_template("picture.html")

额外检查点

  • 确认你的allowed_file函数正确判断了.jpg等允许的文件扩展名,比如:
    def allowed_file(filename):
        ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
        return '.' in filename and \
               filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
    
  • 确保static目录存在,并且有写入权限,否则保存文件时会抛出权限错误。

内容的提问来源于stack exchange,提问作者Benoît

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:15:54