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

Django模板无法展示Amazon S3中已上传PDF的问题求助

解决Django模板无法展示S3中PDF的问题

核心问题分析

你当前的代码存在几个关键问题:

  • 缺少返回所有PDF列表的视图,模板依赖的pdf_documents变量未被传递
  • DisplayPDFView存在代码错误(变量未定义就打印、异常捕获无返回值)
  • 若使用私有S3桶,模板直接调用pdf_file.url无法访问私有文件

分步解决方案

1. 添加PDF列表视图,传递模板所需变量

模板中使用{% for pdf_document in pdf_documents %}循环,但你没有提供对应的列表视图。添加以下代码:

# views.py
from django.views.generic import ListView
from .models import PDFDocument

class PDFListView(ListView):
    model = PDFDocument
    template_name = 'viewCVpage.html'
    context_object_name = 'pdf_documents'  # 与模板变量名保持一致

在urls.py中添加对应路由:

path('view-cv/', views.PDFListView.as_view(), name='view_cv'),

2. 修复DisplayPDFView的代码错误

原视图存在变量未定义就打印、异常捕获无返回值的问题,修复后代码:

# views.py
from django.http import HttpResponse
from django.views import View
import boto3
from django.conf import settings

class DisplayPDFView(View):
    def get(self, request, file_key, *args, **kwargs):
        # 正确初始化S3客户端(需确保settings中配置了密钥和区域)
        s3 = boto3.client(
            's3',
            aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
            aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
            region_name=settings.AWS_S3_REGION_NAME
        )
        bucket_name = settings.AWS_STORAGE_BUCKET_NAME
    
        try:
            response = s3.get_object(Bucket=bucket_name, Key=file_key)
            pdf_content = response['Body'].read()
            # 返回PDF响应
            response = HttpResponse(pdf_content, content_type='application/pdf')
            response['Content-Disposition'] = f'inline; filename="{file_key}"'
            return response

        except s3.exceptions.NoSuchKey:
            return HttpResponse('PDF不存在', status=404)
        except Exception as e:
            print(f"错误详情: {e}")
            return HttpResponse('服务器内部错误', status=500)

3. 适配S3桶的访问权限

情况1:公开S3桶

确保settings.py中配置了正确的S3存储后端,这样pdf_file.url会直接生成公开可访问的S3 URL:

# settings.py
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_ACCESS_KEY_ID = '你的AWS访问密钥ID'
AWS_SECRET_ACCESS_KEY = '你的AWS秘密访问密钥'
AWS_STORAGE_BUCKET_NAME = '你的S3桶名'
AWS_S3_REGION_NAME = '你的桶所在区域(如us-east-1)'
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'

此时模板代码无需修改,保持原有的{{ pdf_document.pdf_file.url }}即可。

情况2:私有S3桶

私有桶无法直接通过pdf_file.url访问,需通过DisplayPDFView代理访问,修改模板代码:

{% for pdf_document in pdf_documents %}
<div class="col-md-4 col-sm-12">
    <div class="card" style="width: 100%; float: left; margin-bottom: 10px;">
        <object data="{% url 'display_pdf' pdf_document.pdf_file.name %}" type="application/pdf" style="width: 100%; height: 400px;">
            <p>无法显示PDF,请<a href="{% url 'display_pdf' pdf_document.pdf_file.name %}">下载PDF</a>。</p>
        </object>
    </div>
</div>
{% endfor %}

注:pdf_document.pdf_file.name对应S3中的文件键(如pdfs/example.pdf)。

4. 验证数据库记录与模板路径

  • 确认Django数据库中存在PDFDocument对象(可通过Django Admin查看)
  • 确认viewCVpage.html放在正确的模板目录下(app的templates文件夹或项目根目录的templates文件夹)

内容的提问来源于stack exchange,提问作者Teh yong xian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:38:20