PDF file in Djangoビューを表示することはできますか? ?
そして、それが可能であれば、どのように行われますか?
これは私がこれまで持っているものです-
@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ビューで出力したい場合、ファイルの内容を応答にダンプするだけです。適切なMIMEタイプで送信します。
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には、特にファイルを返すためのクラス 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マシンで作業している場合、pdfはrb
ではなくr
として開く必要があります。
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()
メソッドがありませんでした。
こちら のガイダンスを探しました。オブジェクトを1つだけ表示したかったので、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を開く良い例を示しています。
それは私のために働いた
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)