Für die Erzeugung von PDF-Dokumenten gibt es verschiedene Möglichkeiten. Wir wollen die Bibliothek pisa nutzen, die ein html2pdf Konverter ist.
Zuerst müssen alle nötigen Pakete installiert werden:
$ pip install pisa PIL html5lib httplib2 pyPdf reportlab
Zur Installation von PIL müssen unter Linux die folgenden Pakete installiert sein:
Für OS X muss man zum Beispiel mit Homebrew die Unterstützung für das JPG Format installieren:
$ brew install jpeg
Dann schreibst du in cookbook/views.py: einen generischen View zum Erzeugen von PDF Dateien:
import cStringIO as StringIO
from django.http import HttpResponse
from django.views.generic import DetailView
import ho.pisa as pisa
class PDFView(DetailView):
def render_to_pdf(self, html):
pdf = StringIO.StringIO()
pisa.CreatePDF(html, pdf, encoding='utf-8')
pdf.seek(0)
return pdf
@property
def filename(self):
return getattr(self.get_object(), self.slug_field)
def render_to_response(self, context, **response_kwargs):
tpl = super(PDFView, self).render_to_response(context, **response_kwargs)
tpl.render()
pdf = self.render_to_pdf(tpl.rendered_content)
response = HttpResponse(pdf, mimetype='application/pdf')
response['Content-Disposition'] = 'attachment; filename=%s.pdf' % self.filename
return response
Jetzt fügst du den URL recipes_recipe_detail_pdf zu recipes/urls.py hinzu:
from .views import RecipeDetailView, RecipePDFView
urlpatterns += patterns('',
url(r'^rezept/(?P<slug>[-\w]+)/$', RecipeDetailView.as_view(),
name='recipes_recipe_detail'),
url(r'^rezept/(?P<slug>[-\w]+)/pdf/$', RecipePDFView.as_view(),
name='recipes_recipe_detail_pdf'),
url(r'^$', RecipeListView.as_view(), name='recipes_recipe_index'),
)
Und nun erstellst mit Hilfe des generischen PDF Views eine View für die PDFs der Rezepte in recipes/views.py:
from utils import PDFView
class RecipePDFView(PDFView):
model = Recipe
template_name = 'recipes/detail_pdf.html'
Jetzt fehlt noch das HTML Template, dass die Vorlage für das PDF ist. Erstelle er hier recipes/templates/recipes/detail_pdf.html:
{% extends "base.html" %}
{% block title %}{{ block.super }} - {{ object.title }}{% endblock %}
{% block toggle_login %}{% endblock %}
{% block content %}
{% load recipes %}
<h2>{{ object.title }}</h2>
<p>Schwierigkeitsgrad: {{ object.get_difficulty_display }}</p>
<p>Ergibt {{ object.number_of_portions }}
Portion{{ object.number_of_portions|pluralize:"en" }}.</p>
<h3>Zutaten</h3>
{{ object.ingredients|linebreaks }}
<h3>Zubereitung</h3>
{{ object.preparation|linebreaks }}
<p>Zubereitungszeit: {{ object.time_for_preparation }} Minuten</p>
<p>Autor: {{ object.author }}</p>
<h4>Kategorie{{ object.category.count|pluralize:"n" }}</h4>
<ul>
{% for category in object.category.all %}
<li>{{ category.name }}</li>
{% endfor %}
</ul>
{% get_related_recipes object 5 as related_recipes %}
{% if related_recipes %}
<h4>Verwandte Rezepte</h4>
<ul>
{% for recipe in related_recipes %}
<li>{{ recipe.title }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
Und füge als letzten Schritt eine Link zum PDF in das Template für ein Rezept ein recipes/templates/recipes/detail.html:
<a href="{% url recipes_recipe_detail_pdf object.slug %}">Rezept als PDF herunterladen</a>
Jetzt kannst du das Rezept auch als PDF ansehen.