2012-08-02 53 views
15

Có thể hiển thị tệp PDF trong chế độ xem chế độ xem Django, thay vì khiến người dùng phải tải xuống tệp đó để xem không?Cách hiển thị tệp PDF ở chế độ xem Django

Và nếu có thể, nó sẽ được thực hiện như thế nào?

Đây là những gì tôi có cho đến nay -

@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 

Trả lời

23

Simplistically, nếu bạn có một tập tin PDF và bạn muốn đầu ra nó thông qua một cái nhìn Django, tất cả các bạn cần làm là đổ nội dung tập tin vào trả lời và gửi nó với mimetype thích hợp.

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 

Bạn có thể có lẽ chỉ trả lại phản ứng trực tiếp mà không chỉ định Content-Disposition, nhưng điều đó tốt hơn chỉ ra ý định của bạn và cũng cho phép bạn chỉ định tên tập tin chỉ trong trường hợp người dùng quyết định để lưu nó.

Ngoài ra, lưu ý rằng chế độ xem ở trên không xử lý được trường hợp tệp không thể mở hoặc đọc vì bất kỳ lý do gì. Vì nó được thực hiện với with, nó sẽ không tăng bất kỳ ngoại lệ nào, nhưng bạn vẫn phải trả về một số loại phản hồi. Tuy nhiên, bạn có thể chỉ cần đặt một số Http404 hoặc một cái gì đó.

+0

Nó không làm việc cho tôi cho đến khi tôi đã thay đổi 'Mimetype = 'application/pdf' thành 'contenttype =' application/pdf'' –

+2

content_type, cũng pdf.closed không có hiệu lực ở đó – amchugh89

+0

là nó ok sự trở lại trước khi đóng tập tin? Tôi nghĩ là không. – azuax

1

Trình duyệt không phải là trình đọc PDF (trừ khi chúng có plugin/bổ trợ phù hợp).

Bạn có thể muốn hiển thị PDF dưới dạng HTML thay thế, có thể được thực hiện from the backend hoặc the frontend.

5

Đưa ra nội tuyến; nếu bạn muốn tệp của mình được đọc từ máy chủ. Và cũng có thể, các HttpResponse kwarg mimetype đã được thay thế bởi 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 
1

Đây là một tình huống điển hình cho việc hiển thị một PDF sử dụng quan điểm dựa trên lớp:

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()) 

Đối tạo pdf của riêng bạn với reportlab xem Django project Docs on PDF Generation.

Phản hồi của Chris Pratt cho thấy một ví dụ điển hình về việc mở các tệp PDF hiện có.

6

Nếu bạn đang làm việc trên máy tính Windows, bạn phải mở pdf là rb không phải 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 
+0

Mở và hiển thị pdf làm việc cho tôi bằng cách sử dụng 'r'. – yndolok

10

Django có một lớp dành riêng để trả lại tệp, FileResponse. Nó truyền các tập tin, do đó bạn không phải đọc toàn bộ tập tin vào bộ nhớ trước khi trả lại. Ở đây bạn đi:

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() 

Nếu bạn có tập tin thực sự lớn hoặc nếu bạn đang làm điều này rất nhiều, một lựa chọn tốt hơn có lẽ sẽ là để phục vụ những tập tin bên ngoài của Django sử dụng cấu hình máy chủ bình thường.

0

nó làm việc cho tôi

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

Sau câu trả lời @ radtek của trên, chúng tôi quyết định nghiên cứu một màn hình xem dựa trên lớp. Tôi đã cố gắng sử dụng View nhưng không có phương thức get_context_data().

Tôi đã xem here để được hướng dẫn. Tôi đã giải quyết cho BaseDetailView vì tôi muốn hiển thị chỉ một đối tượng.

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 

Commentary

1 dòng này truy cập một tên lập luận pk thông qua url gọi xem.

2 Dòng này nhận đối tượng mô hình pdf thực tế.

3 Tôi đã xác định phương thức filename(self): return os.path.basename(self.file.name) trong mô hình của mình để giúp tôi chỉ lấy tên tệp và phần mở rộng.

4 Dòng này nhận được tệp hoàn chỉnh.

Sau đó, sử dụng phản hồi tệp như được giải thích trong các câu trả lời ở trên. Ngoài ra, hãy nhớ sử dụng rb để đọc tệp pdf

-1

Tôi chỉ đang ném điều này ra khỏi đó.

Bạn chỉ cần thêm tiếp tục PDF của mình vào tệp tĩnh.

Nếu bạn đang sử dụng White Noise để phục vụ các tệp tĩnh của mình, thì bạn thậm chí không cần phải thực hiện chế độ xem. Sau đó, truy cập sơ yếu lý lịch của bạn tại vị trí tĩnh.

tôi đã thêm tôi, ở đây là: https://www.jefferythewind.com/static/main/resume/TIm-D_Nice.pdf

Cảnh báo: Đây không giải quyết được yêu cầu login_required trong câu hỏi

Các vấn đề liên quan