How to do it...

Execute the following steps to complete the recipe:

  1.  We will create the template with which the document will be rendered, as follows:
{# templates/cv/cv_pdf.html #}
{% load static %}
{% get_media_prefix as MEDIA_URL %}
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>{{ cv }}</title>
<style>
@page {
size: a4 portrait;
margin: 2.5cm 1.5cm;

@frame footer_frame {
-pdf-frame-content: footer_content;
bottom: 0;
margin-left: 0;
margin-right: 0;
height: 1cm;
}
}

#footer_content {
color: #666;
font-size: 10pt;
text-align: center;
}

h1 { text-align: center; }
th, td { vertical-align: top; }
/* ... additional styles here ... */
</style>
</head>
<body>
<div>
<h1>Curriculum Vitae for {{ cv }}</h1>

<table><tr>
<td>
<h2>Contact Information</h2>
<p><b>Email:</b> {{ cv.email }}</p>
</td>
<td align="right">
<img src="{% static 'site/img/smiley.jpg' %}"
width="100" height="100" />
</td>
</tr></table>

<h2>Experience</h2>

{% for experience in cv.experience_set.all %}
<h3>{{ experience.position }} at {{ experience.company }}</h3>
<p><b>
{{ experience.from_date|date:"F Y" }} -
{{ experience.till_date|date:"F Y"|default:"present" }}
</b></p>
<p>
<b>Skills gained</b><br>
{{ experience.skills|linebreaksbr }}
</p>
{% endfor %}
</div>
<pdf:nextpage>
<div>
This is an empty page to make a paper plane.
</div>
<div id="footer_content">
Document generated at {% now "Y-m-d" %} |
Page <pdf:pagenumber> of <pdf:pagecount>
| Smiley obtained from clipartextras.com
</div>
</body>
</html>
  1. Let's create the download_cv_pdf() view. This view renders the HTML template and then passes the rendered string to the pisa PDF creator:
# cv/views.py
import os

from django.conf import settings
from django.http import HttpResponse, HttpResponseServerError
from django.shortcuts import get_object_or_404, render_to_response
from django.template.loader import render_to_string
from django.utils.text import slugify
from xhtml2pdf import pisa

from .models import CurriculumVitae


def link_callback(uri, rel):
# convert URIs to absolute system paths
if uri.startswith(settings.MEDIA_URL):
path = os.path.join(settings.MEDIA_ROOT,
uri.replace(settings.MEDIA_URL, ""))
elif uri.startswith(settings.STATIC_URL):
path = os.path.join(settings.STATIC_ROOT,
uri.replace(settings.STATIC_URL, ""))
else:
# handle absolute uri (ie: http://my.tld/a.png)
return uri

# make sure that file exists
if not os.path.isfile(path):
raise Exception(
"Media URI must start with "
f"'{settings.STATIC_URL}' or '{settings.MEDIA_URL}'")
return path


def download_cv_pdf(request, cv_id):
cv = get_object_or_404(CurriculumVitae, pk=cv_id)

response = HttpResponse(content_type="application/pdf")
response["Content-Disposition"] =
f"attachment; filename='{slugify(cv, True)}.pdf'"

html = render_to_string("cv/cv_pdf.html", {"cv": cv})
status = pisa.CreatePDF(html,
dest=response,
link_callback=link_callback)

if status.err:
response = HttpResponseServerError(
"The PDF could not be generated.")

return response
  1. Create a rule in urls.py for the view that will download a PDF document of a résumé by the ID of the CurriculumVitae model instance, as follows:
# cv/urls.py
from django.urls import path

from .views import download_cv_pdf


urlpatterns = [
path('<int:pk>/pdf/', download_cv_pdf, name="cv-pdf"),
]
  1. Add our cv URLs to the project:
    # project/urls.py
from django.urls import include, path

urlpatterns = [
# ...
path('cv/', include('cv.urls')),
]
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.179.225