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

如何在Django中展示MySQL数据库Blob存储的PDF文件?

搞定MySQL Blob存储的PDF展示问题!

你现在用临时文件传递PDF的方式可以简化不少——直接让后端把数据库里的Blob二进制数据以正确的HTTP响应返回给前端,浏览器就能原生渲染PDF了,既省事儿又避免临时文件的管理麻烦。下面分后端处理和前端展示两部分给你具体方案:

后端:读取Blob并返回PDF响应

看你上传代码里用了request.FILES,大概率是Flask或Django这类Python框架,我分别给你写两种场景下的代码:

Flask版本

from flask import Response, get_db  # get_db替换成你自己获取数据库连接的方法

@app.route('/view-pdf/<int:report_id>')
def view_pdf(report_id):
    # 先做权限校验!比如检查当前登录用户是否有权限看这个PDF
    # if not has_permission(current_user, report_id):
    #     return "无权限访问", 403

    db = get_db()
    fcursor = db.cursor()
    fcursor.execute("SELECT DOC FROM REPORTS WHERE id = %s", (report_id,))
    result = fcursor.fetchone()
    fcursor.close()
    db.close()
    
    if not result:
        return "该PDF不存在", 404
    
    pdf_data = result[0]
    # 返回带正确头的响应,让浏览器识别是PDF并直接展示
    return Response(
        pdf_data,
        mimetype='application/pdf',
        headers={
            'Content-Disposition': 'inline; filename="report_{}.pdf"'.format(report_id)
        }
    )

Django版本

from django.http import HttpResponse
from django.db import connection

def view_pdf(request, report_id):
    # 权限校验不能少!
    # if not request.user.has_perm('view_report', report_id):
    #     return HttpResponse("无权限访问", status=403)

    with connection.cursor() as cursor:
        cursor.execute("SELECT DOC FROM REPORTS WHERE id = %s", [report_id])
        result = cursor.fetchone()
        if not result:
            return HttpResponse("该PDF不存在", status=404)
        
        pdf_data = result[0]
        response = HttpResponse(pdf_data, content_type='application/pdf')
        response['Content-Disposition'] = 'inline; filename="report_{}.pdf"'.format(report_id)
        return response

这里的核心是设置两个HTTP头:

  • mimetype(或content_type)设为application/pdf,告诉浏览器这是PDF文件
  • Content-Disposition用inline表示在浏览器内直接打开,而不是触发下载;如果想保留下载选项,也可以留空或者改成attachment(不过你要的是展示,inline更合适)

前端:模板里嵌入PDF展示

后端接口写好后,前端模板里用<iframe>、<embed>或者<object>标签加载就行,<iframe>的兼容性最好:

Flask Jinja2模板示例

<iframe src="{{ url_for('view_pdf', report_id=report.id) }}" 
        width="100%" 
        height="800px"
        frameborder="0">
    你的浏览器不支持PDF预览,请<a href="{{ url_for('view_pdf', report_id=report.id) }}">点击下载</a>
</iframe>

Django模板示例

<iframe src="{% url 'view_pdf' report.id %}" 
        width="100%" 
        height="800px"
        frameborder="0">
    你的浏览器不支持PDF预览,请<a href="{% url 'view_pdf' report.id %}">点击下载</a>
</iframe>

为啥不推荐临时文件?

之前的临时文件方案有几个坑:

  • 要额外写代码创建、管理、清理临时文件,服务器崩溃时容易留残留文件
  • 多用户同时访问时可能出现文件竞争的问题
  • 直接返回二进制数据流更高效,减少磁盘IO操作

额外提醒

  • 权限校验一定要加:在view_pdf函数开头必须检查当前用户是否有权限查看该PDF,别让任何人都能通过ID访问
  • 如果PDF文件很大(比如超过10MB),存在Blob里会拖慢数据库性能,这时建议把大文件存在本地文件系统或对象存储,数据库只存文件路径,读写效率会高很多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:42:38