如何在Django模板中同时展示API返回的数据与图片/PDF文件
Django自动检测文件类型并展示图片/PDF的实现方案
问题所在
当前代码存在两个关键问题:
- 直接将API返回的二进制文件内容(
response1.content)传给模板,HTML无法直接解析二进制数据; - 未做文件类型检测,模板仅固定使用
iframe标签,无法同时适配图片和PDF两种格式。
解决步骤
1. 调整视图函数
要让模板正确展示文件,需完成以下操作:
- 获取文件的MIME类型(优先从API响应头提取,无响应头则通过文件内容检测);
- 将二进制文件内容转换为Base64编码,生成可直接在HTML中使用的Data URI;
- 将发票数据、文件类型、Data URI一并传给模板。
修改后的视图代码:
import base64 import magic # 需先安装依赖:pip install python-magic def get_invoice_details(request, myid=''): try: # 获取发票基础数据 mark_url = urlDataApiEndpoint data = {"myId": myid} response = requests.post(url=mark_url, headers=header, json=data) inv_data = response.json() # 获取文件二进制内容 mark_url1 = urlFileApiEndPoint data1 = {"myid": myid} response1 = requests.post(mark_url1, headers=header, json=data1) file_content = response1.content # 获取文件MIME类型:优先用响应头,无则用magic检测 mime_type = response1.headers.get('Content-Type') if not mime_type: mime_type = magic.from_buffer(file_content, mime=True) # 转换为Base64编码的Data URI base64_content = base64.b64encode(file_content).decode('utf-8') file_data_uri = f"data:{mime_type};base64,{base64_content}" # 传递变量到模板 return render(request, 'myTemplate.html', { 'inv_data': inv_data, 'file_data_uri': file_data_uri, 'mime_type': mime_type }) except KeyError as e: print(f"KeyError: {e}") # 可添加错误处理逻辑,比如返回错误页面 return render(request, 'error.html')
2. 修改模板文件
根据MIME类型分支渲染:图片使用<img>标签,PDF使用<iframe>标签,其他类型提示不支持。
修改后的myTemplate.html代码:
<div>{{ inv_data.invno }}</div> <div> {% if mime_type in 'image/jpeg,image/jpg' %} <img src="{{ file_data_uri }}" alt="发票图片" style="height:100%; width:200px;"> {% elif mime_type == 'application/pdf' %} <iframe src="{{ file_data_uri }}#view=fitH" title="PDF文件" height="100%" width="200px"></iframe> {% else %} <p>不支持的文件类型</p> {% endif %} </div>
额外提示
- 若不想依赖
python-magic,可完全依靠API返回的Content-Type响应头,前提是第三方API会准确返回该字段; - Base64编码会使文件体积增大约30%,若文件较大,建议将文件保存到服务器静态目录,再向模板传递文件URL(当前方案更适合小文件场景)。
内容的提问来源于stack exchange,提问作者Achal
相关产品推荐
相关产品推荐

