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
相关产品推荐
相关产品推荐

