2013-08-14 5 views
11

Könnte mir bitte jemand ein umfassendes Beispiel geben, wie man eine view in django erhält, um eine PDF unter Verwendung wkhtmltopdf zurückzugeben. Es gibt eine begrenzte Anzahl von Beispielen, die mit django-wkhtmltopdf kommen, und sie setzen ein Niveau von Wissen voraus, das ich gerade nicht habe. Ich habe durch den Quellcode geschaut, aber ich kann nicht Kopf oder Zahl machen, wie man es benutzt (zum Beispiel was ist der Unterschied zwischen PDFTemplateView und PDFTemplateResponse?!?)Erstellen von PDFs mit Django (wkhtmltopdf)

Ich wäre sehr dankbar für jede Hilfe.

BTW (Ich bin mit Vorlagen für die Kopf- und Fußzeile sowie)

EDIT

def some_view(request,sID): 
    something = get_object_or_404(Something,id=sID) 
    return render_to_response('something.html', {'something':something}, context_instance=RequestContext(request)) 

Wie würde ich die folgende einfache Ansicht hol mir zu schaffen, mit einem pdf statt von einer html Datei?

EDIT 2

ich zur Zeit das Spiel mit:

def pdf_view(request,sID): 
    template = 'pdf.html' 
    something = get_object_or_404(Something,id=sID) 
    context = { 
     'something' : Something, 
     'object_for_header_and_footer': something.object_for_header_and_footer, 
    } 
    cmd_options = settings.WKHTMLTOPDF_CMD_OPTIONS 

    return PDFTemplateResponse(request=request, 
     context=context, 
     template=template, 
     filename='something', 
     header_template='header.html', 
     footer_template='footer.html', 
     cmd_options=cmd_options) 

aber ich bin immer 'str' object has no attribute 'update' in /usr/local/lib/python2.7/dist-packages/wkhtmltopdf/utils.py in wkhtmltopdf, line 74. Ich weiß nicht, ob ich anfangen soll, wchhtmltopdf zu hacken?!?!

+1

Die normale Ansicht und PDFTemplateResponse funktioniert für mich. Ich habe die WKHTMLTOPDF_CMD_OPTIONS nicht angegeben. – allcaps

Antwort

17

Der Unterschied zwischen PDFTemplateView und PDFTemplateResponse besteht darin, dass es sich bei der Ansicht um eine klassenbasierte Ansicht handelt. Und PDFTemplateResponse rendert die PDF-Daten und setzt das richtige response headers. So fügen Sie Kopf- und Fußzeile:

# urls.py 

from django.conf.urls.defaults import * 
from wkhtmltopdf.views import PDFTemplateView 


    urlpatterns = patterns('', 
     ... 
     url(r'^pdf/$', PDFTemplateView.as_view(template_name='my_template.html', 
       filename='my_pdf.pdf', 
       header_template='my_header_template.html', 
       footer_template='my_footer_template.html', 
       ... 
       ), name='pdf'), 
    ) 

Eröffnung pdf/in Ihrem Browser einen Download von my_pdf.pdf basierend auf dem my_template.html, my_header_template.html und my_footer_template.html starten.

Die advanced example zeigt, wie PDFTemplateView abgeleitet und die Logik von PDFTemplateView geändert wird. Um zu verstehen, was passiert, lesen Sie Using class based views.

Wie header_template und footer_template können Sie eine response_class definieren. Da PDFTemplateResponse der Standardwert ist, müssen Sie ihn nicht definieren.

EDIT

Die folgende einfache Ansicht, die Sie mit einem pdf statt einer HTML zur Verfügung stellt. Dies verwendet nicht django-wkhtmltopdf. Sie könnten wkhtmltopdf in Ihrer html2pdf-Funktion verwenden.

def some_view(request): 
    t = loader.get_template('myapp/template.html') 
    c = RequestContext(request, {'foo': 'bar'}) 
    html = t.render(c) 
    pdf_data = html2pdf(html) # Your favorite html2pdf generator 
    response = HttpResponse(pdf_data, content_type='application/pdf') 
    response['Content-Disposition'] = 'attachment; filename="some_filename.pdf"' 
    return response 

EDIT 2

eine einfache Ansicht mit Kontext:

template.html

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8" /> 
    <title>Untitled</title> 
</head> 
<body> 
    <h1>{{ title }}</h1> 
</body> 
</html> 

URLs.py

from views import MyPDFView 

urlpatterns = patterns('', 
    (r'^pdf/', MyPDFView.as_view()), 
) 

views.py

from django.views.generic.base import View 
from wkhtmltopdf.views import PDFTemplateResponse 

class MyPDFView(View): 
    template='template.html' 
    context= {'title': 'Hello World!'} 

    def get(self, request): 
     response = PDFTemplateResponse(request=request, 
             template=self.template, 
             filename="hello.pdf", 
             context= self.context, 
             show_content_in_browser=False, 
             cmd_options={'margin-top': 50,}, 
             ) 
     return response 

EDIT 3

Wenn Sie eine Detailview verwenden, können Sie das Objekt Kontext hinzufügen:

url(r'^books/(?P<pk>\d+)/$', MyPDFView.as_view(), name='book-detail'), 


class MyPDFView(DetailView): 
    template='pdftestapp/template.html'  
    context= {'title': 'Hello World!'} 
    model = Book 

    def get(self, request, *args, **kwargs):   
     self.context['book'] = self.get_object() 

     response=PDFTemplateResponse(request=request, 
            template=self.template, 
            filename ="hello.pdf", 
            context=self.context, 
            show_content_in_browser=False, 
            cmd_options={'margin-top': 50,} 
            ) 
     return response 
+0

Das ist gut für das Rendern von statischen '.html' (ich nehme an), aber was passiert, wenn Sie' def something.views.something_view (request, someID) 'wollen, um eine' pdf' anstatt 'html' zu rendern? – Sevenearths

+0

(und auf einer Seite beachten, warum statische '* .html' Dateien an Attribute mit' template' in ihnen übergeben werden. Es macht keinen Sinn?!? Sicherlich, wenn ein Attribut hat 'template' in es es fragt ein 'view'. Ist es nicht?!?) – Sevenearths

+1

Ich fühle mich ein bisschen wie' User.objects.filter (clue__lt = 0) ' – Sevenearths

2

Hmm der Fehler zeigt an, dass Sie irgendwo eine Zeichenfolge übergeben, die Sie nicht sollten.

Nach seiner source code Überprüfung, ich denke, in settings.py Sie haben WKHTMLTOPDF_CMD_OPTIONS als String, so etwas wie

WKHTMLTOPDF_CMD_OPTIONS = 'some_option_here' 

Aber Sie sollten einen dict dort zuweisen:

WKHTMLTOPDF_CMD_OPTIONS = { 
    'quiet': True, 
} 

Ansonsten sollten Sie den Code funktionieren .