web-dev-qa-db-ja.com

PDFファイルをDjango=ビューで表示するには?

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
27
SImon

簡単に言えば、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または何かを上げることができます。

32
Chris Pratt

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の外部でこれらのファイルを提供することをお勧めします。

29
Flimm

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
8
MKM

インラインで取り出します。ファイルをサーバーから読み取る場合。また、HttpResponse kwarg mimetypecontent_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
6
gajanan hegde

上記の@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ファイルを読み取ることも忘れないでください

3
chidimo

以下は、クラスベースのビューを使用して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を開く良い例を示しています。

2
radtek

ブラウザはPDFリーダーではありません(適切なプラグイン/アドオンがない限り)。

代わりにPDFをHTMLとしてレンダリングすることができます。これは バックエンドから または フロントエンド で実行できます。

0
Gonzalo

それは私のために働いた

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)
0
German Lopez