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

Django项目中PDF媒体文件无法在网页显示的问题求助

Django iframe显示PDF报错问题排查与修复

问题概述

已排查各类配置,媒体图片可正常显示,但通过FileField上传的PDF文件,使用iframe加载时出现报错,且已确认文件链接正确。相关配置代码如下:

配置代码

settings.py

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/

STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')

# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'


X_FRAME_OPTIONS = 'SAMEORIGIN'

show_pdf.html

<iframe
        src="{{pdf.url}}"
    frameBorder="0"
    scrolling="auto"
    height="1200px"
    width="1200px"
></iframe>

models.py

class File_pdf(models.Model):
    title = models.CharField(max_length=50)
    pdf = models.FileField(upload_to='portfolio/pdfs')
    main_resume = models.BooleanField(default=False,help_text="set only one pdf as the main pdf for the main page")

    def __str__(self):
        return self.title

urls.py

urlpatterns = [
        path('admin/', admin.site.urls),
        path('',include('portfolio.urls')),
        path('blog/',include('blog.urls'))
]

urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

views.py

def pdf_view(request,pdf_id,resume):
    dic = {}
    if resume == "yes":
        pdf_files = File_pdf.objects.filter(main_resume=True)
        pdf_file = pdf_files[0]
        dic['pdf'] = pdf_file.pdf
        dic['title'] = pdf_file.title
    else:
        pdf_files = get_object_or_404(File_pdf,pk=pdf_id)
        pdf_file = pdf_files[0]
        dic['pdf'] = pdf_file.pdf
        dic['title'] = pdf_file.title

核心问题与修复步骤

1. 视图函数的致命错误

else分支中,get_object_or_404(File_pdf,pk=pdf_id)返回的是单个File_pdf对象,而非QuerySet集合,直接调用pdf_files[0]会抛出TypeError: 'File_pdf' object is not subscriptable错误,导致视图无法正常渲染,这是iframe加载失败的直接原因之一。同时原视图缺少模板渲染返回语句,会触发500服务器错误。

修复后的views.py:

from django.shortcuts import get_object_or_404, render

def pdf_view(request,pdf_id,resume):
    dic = {}
    if resume == "yes":
        # 增加空集合判断,避免索引报错
        pdf_files = File_pdf.objects.filter(main_resume=True)
        if pdf_files.exists():
            pdf_file = pdf_files[0]
            dic['pdf'] = pdf_file.pdf
            dic['title'] = pdf_file.title
        else:
            # 可添加无主PDF的 fallback 逻辑
            pass
    else:
        pdf_file = get_object_or_404(File_pdf,pk=pdf_id)
        dic['pdf'] = pdf_file.pdf
        dic['title'] = pdf_file.title
    # 必须返回模板渲染结果
    return render(request, 'show_pdf.html', dic)

2. 其他潜在排查点

  • 浏览器PDF渲染支持:直接在新标签页打开{{pdf.url}}链接,确认PDF文件本身能否正常打开,排除浏览器内置阅读器禁用的可能。
  • 文件权限问题:检查MEDIA_ROOT目录下的PDF文件是否具备可读权限,确保服务器进程能读取文件内容。
  • MIME类型配置:确保服务器返回的PDF文件MIME类型为application/pdf,开发环境下Django的static服务会自动处理,生产环境需在Nginx/Apache等服务器中配置对应规则。
  • 生产环境媒体服务:生产环境不能依赖static()函数提供媒体文件服务,需配置Nginx/Apache直接托管MEDIA目录,或使用云存储服务。

内容的提问来源于stack exchange,提问作者virgilio murillo ochoa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 07:18:19