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

Flask+mysql.connector:MySQL数据库文件无法显示为锚点链接的问题

解决Flask中MySQL文件无法展示为锚点链接的问题

问题根源分析

你的代码存在三个核心问题:

  1. 后端未传递文件数据到模板:当前后端仅处理文件上传逻辑,没有从数据库查询已上传文件的信息并传递给前端模板,导致allFiles变量不存在,循环无法执行。
  2. 模板语法错误:前端循环标签写成了{{% for ... %}},正确的Jinja2循环语法是{% for ... %},多余的大括号会导致模板解析失败。
  3. 缺少文件访问路由:数据库中存储的是二进制文件内容,无法直接作为链接地址,需要单独的路由来读取并返回文件内容。

分步解决方法

1. 后端添加文件查询逻辑,传递数据到模板

修改ImageUpload视图函数,在GET请求时查询数据库中的文件记录,将数据传给模板:

@app.route("/ImageUpload", methods=["POST", "GET"])
def ImageUpload():
    if is_authenticated():
        googleAccountName = session['name']
        response = requests.get(f'https://people.googleapis.com/v1/people/{session["google_id"]}?personFields=photos&key={api_key}')
        profile_pic_url = response.json()['photos'][0]['url']
        
        # 查询已上传的文件基础信息(避免直接读取二进制数据占用内存)
        mycursor = mydb.cursor(dictionary=True)  # 使用字典游标,方便通过字段名取值
        mycursor.execute("SELECT id, Unit, File_Type FROM ImageAndWord")
        allFiles = mycursor.fetchall()
        
        if request.method == 'POST':
            # 原有上传逻辑保持不变
            selected_unit = request.form['Units']
            
            if 'files[]' not in request.files:
                flash('No file uploaded')
                return redirect(request.url)
                
            files = request.files.getlist('files[]')
            
            if not files:
                flash('No file uploaded')
                return redirect(request.url)
            
            allowed_extensions = set(['png', 'jpg', 'jpeg', 'pdf'])
            for file in files:
                if file.filename.split('.')[-1] not in allowed_extensions:
                    flash('Invalid file type: ' + file.filename)
                    return redirect(request.url)
                
            mycursor = mydb.cursor()
            for file in files:
                sql = "INSERT INTO ImageAndWord (Unit, File_Type, File) VALUES (%s, %s, %s)"
                val = (selected_unit, file.filename.split('.')[-1], file.read())
                mycursor.execute(sql, val)
                mydb.commit()

            flash('Files uploaded successfully!')
            return redirect(request.url)
    
        # 传递文件数据到模板
        return render_template("Imageupload1.html", 
                               googleAccname=googleAccountName, 
                               profile_pic=profile_pic_url,
                               allFiles=allFiles)
    # 未认证时跳转登录页(可根据实际需求调整)
    return redirect("/login")

2. 修复前端模板语法错误

修正循环标签的语法错误,同时调整链接文本和地址,指向后续创建的文件访问路由:

{% for file in allFiles %}
    <a href="/download/{{ file.id }}">文件 {{ loop.index }} (单元: {{ file.Unit }})</a><br>
{% endfor %}
  • loop.index是Jinja2内置变量,用于显示循环序号,替代你原来的fileCount
  • 链接地址指向/download/文件ID,后续会创建这个路由

3. 创建文件访问/下载路由

添加新路由,根据文件ID从数据库读取二进制内容并返回给浏览器:

from flask import abort, Response

@app.route("/download/<int:file_id>")
def download_file(file_id):
    if not is_authenticated():
        return redirect("/login")
        
    mycursor = mydb.cursor(dictionary=True)
    mycursor.execute("SELECT File, File_Type FROM ImageAndWord WHERE id = %s", (file_id,))
    file_data = mycursor.fetchone()
    
    if not file_data:
        abort(404)  # 文件不存在时返回404
    
    # 根据文件类型设置对应的Content-Type
    mime_types = {
        'png': 'image/png',
        'jpg': 'image/jpeg',
        'jpeg': 'image/jpeg',
        'pdf': 'application/pdf'
    }
    content_type = mime_types.get(file_data['File_Type'], 'application/octet-stream')
    
    # 返回响应,浏览器会根据文件类型自动处理(图片直接显示,PDF可预览或下载)
    return Response(file_data['File'], mimetype=content_type)

验证步骤

  1. 重启Flask应用
  2. 上传一个测试文件
  3. 刷新/ImageUpload页面,即可看到文件链接
  4. 点击链接,浏览器会根据文件类型显示或下载文件

内容的提问来源于stack exchange,提问作者Amir Khoury

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:25:13