如何在Django视图中显示PDF文件?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Django视图中显示PDF文件?相关的知识,希望对你有一定的参考价值。
是否可以在Django视图中显示PDF文件,而不是让用户下载它来查看它?
如果有可能,它会怎么做?
这是我到目前为止 -
@login_required
def resume(request, applicant_id):
#Get the applicant's resume
resume = File.objects.get(applicant=applicant_id)
fsock = open(resume.location, 'r')
response = HttpResponse(fsock, mimetype='application/pdf')
return response
简单地说,如果您有一个PDF文件并且想要通过Django视图输出它,那么您需要做的就是将文件内容转储到响应中并使用适当的mimetype发送它。
def pdf_view(request):
with open('/path/to/my/file.pdf', 'r') as pdf:
response = HttpResponse(pdf.read(), mimetype='application/pdf')
response['Content-Disposition'] = 'inline;filename=some_file.pdf'
return response
pdf.closed
您可以直接返回响应而不指定Content-Disposition,但这更好地表明了您的意图,并且允许您指定文件名以防用户决定保存它。
另请注意,上面的视图无法处理无论出于何种原因无法打开或读取文件的情况。由于它是使用with
完成的,因此不会引发任何异常,但您仍然必须返回某种响应。你可以简单地举起一个Http404
或其他东西。
最简单的方法是使用模板中的锚点。例如,如果您正在使用Django的模板引擎(因为大多数搜索它的人可能都是这样),只需通过锚点将其作为静态文件提供。
在包含文件链接的模板中,添加到最顶层
{% load static %}
然后,无论您想要链接到您的pdf,请放置
<a href="{% static 'relative/path/file.pdf' %}">Click me</a>
第一行告诉Django查看settings.py
中为静态文件配置的目录。您在anchor标记中使用的路径是相对于您在settings.py
中配置为静态目录的任何目录。当您单击呈现的链接时,它应该在浏览器中显示PDF,前提是您正确地修改了静态文件。
Django有一个专门用于返回文件的类,FileResponse。它会传输文件,因此您无需在返回之前将整个文件读入内存。干得好:
from django.http import FileResponse, Http404
def pdf_view(request):
try:
return FileResponse(open('foobar.pdf', 'rb'), content_type='application/pdf')
except FileNotFoundError:
raise Http404()
如果您有非常大的文件或者您正在做很多事情,那么更好的选择可能是使用普通服务器配置在Django之外提供这些文件。
如果您正在使用Windows机器,则必须以rb
而不是r
打开pdf。
def pdf_view(request):
with open('/path / to /name.pdf', 'rb') as pdf:
response = HttpResponse(pdf.read(),content_type='application/pdf')
response['Content-Disposition'] = 'filename=some_file.pdf'
return response
取出内联;如果您希望从服务器读取您的文件。此外,HttpResponse
kwarg mimetype
已被content_type
取代:
(response['Content-Disposition'] = 'inline;filename=some_file.pdf')
def pdf_view(request):
with open('/app/../Test.pdf', 'r') as pdf:
response = HttpResponse(pdf.read(),content_type='application/pdf')
response['Content-Disposition'] = 'filename=some_file.pdf'
return response
pdf.closed
按照上面的@radtek的回答,我决定调查一个基于类的视图显示。我试图使用View
但它没有get_context_data()
方法。
我看了here的一些指导。因为我只想显示一个物体,所以我选择了BaseDetailView
。
from django.http import FileResponse
from django.shortcuts import get_object_or_404
from django.views.generic.detail import BaseDetailView
class DisplayPdfView(BaseDetailView):
def get(self, request, *args, **kwargs):
objkey = self.kwargs.get('pk', None) #1
pdf = get_object_or_404(Pdf, pk=objkey) #2
fname = pdf.filename() #3
path = os.path.join(settings.MEDIA_ROOT, 'docs\' + fname)#4
response = FileResponse(open(path, 'rb'), content_type="application/pdf")
response["Content-Disposition"] = "filename={}".format(fname)
return response
评论
1此行访问由调用视图的url传递的命名参数pk
。
2此行获取实际的pdf模型对象。
3我在我的模型中定义了一个方法filename(self): return os.path.basename(self.file.name)
,以帮助我获得文件名和扩展名。
4此行获取完整的文件路径。
然后使用文件响应,如上面的答案中所述。还记得使用rb
来读取pdf文件
以下是使用基于类的视图显示PDF的典型用例:
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
class DisplayPDFView(View):
def get_context_data(self, **kwargs): # Exec 1st
context = {}
# context logic here
return context
def get(self, request, *args, **kwargs):
context = self.get_context_data()
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'inline; filename="worksheet_pdf.pdf"' # Can use attachment or inline
# pdf generation logic here
# open an existing pdf or generate one using i.e. reportlab
return response
# Remove login_required if view open to public
display_pdf_view = login_required(DisplayPDFView.as_view())
要使用reportlab生成自己的pdf,请参阅Django project Docs on PDF Generation。
Chris Pratt的回复显示了打开现有PDF的一个很好的例子。
浏览器不是PDF阅读器(除非他们有适当的插件/插件)。
您可能希望将PDF呈现为html,这可以通过from the backend或the frontend来完成。
它对我有用
import re, os
import os
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def export_auto_doc(request):
name = request.GET.get('name', "")
filename = "path/to/file"+name+".pdf"
try:
if not re.search("^[a-zA-Z0-9]+$",name):
raise ValueError("Filename wrong format")
elif not os.path.isfile(filename):
raise ValueError("Filename doesn't exist")
else:
with open(filename, 'r') as pdf:
response = HttpResponse(pdf.read(), content_type='application/pdf')
response['Content-Disposition'] = 'inline;filename='+name+'.pdf'
return response
pdf.closed
except ValueError as e:
HttpResponse(e.message)
我只是把它扔到那里。
您只需将PDF简历添加到静态文件即可。
如果您使用白噪声来提供静态文件,那么您甚至不需要进行视图。然后在静态位置访问您的简历。
我加了我的,这里是:https://www.jefferythewind.com/static/main/resume/TIm-D_Nice.pdf
警告:这不能解决问题中的login_required
要求
以上是关于如何在Django视图中显示PDF文件?的主要内容,如果未能解决你的问题,请参考以下文章