django-renderpdf¶
django-renderpdf is a Django application for generating PDFs via Django.
Our intent is to properly integrate into Django, and have a very simple, yet flexible API. We follow common Django patterns, so rendering and exposing PDFs is simple.
Index¶
Installation¶
You’ll first need to install the python package:
pip install django-renderpdf
You don’t need to add it to INSTALLED_APPS
.
This package depends on weasyprint
, which will be installed as a dependency
automatically. However, weasyprint
itself has a few non-Python
dependencies. Make sure the following works before proceeding:
python -c "import weasyprint"
If the above prints an error, please follow weasyprint’s installation documentation.
Usage¶
As a usage example, lets assume we have to print some shipping labels to dispatch a product. We’ll need to generate a PDF file for this to print.
from django.contrib.auth.mixins import LoginRequiredMixin
from django_renderpdf.views import PDFView
from myapp import Shipment
class LabelsView(LoginRequiredMixin, PDFView):
"""Generate labels for some Shipments.
A PDFView behaves pretty much like a TemplateView, so you can treat it as such.
"""
template_name = 'my_app/labels.html'
def get_context_data(self, *args, **kwargs):
"""Pass some extra context to the template."""
context = super().get_context_data(*args, **kwargs)
context['shipments'] = Shipment.objects.filter(
batch_id=kwargs['pk'],
)
return context
If anything in the above example seems completely new, I suggest you review the documentation for Django’s Class-based views.
You still need to include this view in your urls.py
as usual:
from django.urls import path
path(
'/shipments/labels/<int:pk>/',
views.LabelsView.as_view(),
name='shipment_labels',
)
Now visiting /shipments/labels/17
, will return a PDF file which your browser will
render. Note that, since we used the LoginRequiredMixin
, anonymous users will be
redirected to the usual login screen, and then back to this view after login.
API¶
PDFView¶
- class django_renderpdf.views.PDFView(**kwargs)¶
A base class that renders requests as PDF files.
All views that render a PDF must inherit from this base class.
Usage and interface is quite similar to Django’s built-in views. Template context data can be defined via
get_context_data
just like with Django’sTemplateView
subclasses.The following additional attributes allow further customising behaviour of subclasses. These may be overridden by either an attribute or a property:
- template_name: str | None = None¶
The name of the template file that will be rendered into a PDF file. Template discovery works just like any regular Django view.
- allow_force_html: bool = True¶
Allow forcing this view to return a rendered HTML response, rather than a PDF response. If
True
, any requests with the URL parameterhtml=true
will be rendered as plain HTML. This can be useful for debugging, but also allows reusing the same view for exposing both PDFs and HTML.
- prompt_download: bool = False¶
If
True
, users will be prompted to download the PDF file, rather than have it rendered by their browsers.This is achieved by setting the “Content-Disposition” HTTP header. If this attribute is
True
, then eitherdownload_name
orget_download_name()
must be defined.
- download_name: str | None = None¶
When
prompt_download
is set toTrue
, browsers will be instructed to prompt users to download the file, rather than render it.In these cases, a default filename is presented. If you need custom filenames, you may override this attribute with a property:
@property def download_name(self) -> str: return f"document_{self.request.kwargs['pk']}.pdf"
This attribute has no effect if
prompt_download = False
.
The following methods may also be overridden to further customise subclasses:
- url_fetcher(url)¶
Returns the file matching URL.
This method will handle any URL resources that rendering HTML requires (e.g.: images in
img
tags, stylesheets, etc.).The default behaviour will fetch any http(s) files normally, and will also attempt to resolve relative URLs internally.
Generally, you should not need to override this method unless you want to use custom URL schemes. For finer details on its inner workings, see weasyprint’s documentation on url_fetcher.
- get_template_names() List[str] ¶
Return a list of template names to be used for the request.
Must return a list. By default, just returns
[self.template_name]
.New in version 3.0.
- get_download_name() str ¶
Return the default filename when this file is downloaded.
Deprecated since version 3.0: Use
download_name()
as a property instead.
- get_template_name() str ¶
Return the name of the template which will be rendered into a PDF.
Deprecated since version 3.0: Use
get_template_names()
instead.
Helpers¶
- django_renderpdf.helpers.render_pdf(template: ~typing.List[str] | str, file_: ~typing.IO, url_fetcher=<function django_url_fetcher>, context: dict | None = None)¶
Writes the PDF data into
file_
. Note thatfile_
can actually be a Django Response object as well, since these are file-like objects.This function may be used as a helper that can be used to save a PDF file to a file (or anything else outside of a request/response cycle).
- Parameters:
template – A list of templates, or a single template. If a list of templates is passed, these will be searched in order, and the first one found will be used.
file – A file-like object (or a Response) where to output the rendered PDF.
url_fetcher – See weasyprint’s documentation on url_fetcher.
context – Context parameters used when rendering the template.
Changelog¶
v4.1.0¶
Fixed documentation not rendering on readthedocs.
Add support for Python 3.11.
Add support for Django 4.1 and 4.2.
v4.0.0¶
Dropped support for Python 3.6.
Dropped support for Python 3.7.
Supported Python versions are now 3.8, 3.9 and 3.10.
Supported Django versions are now 3.2 and 4.0.
v3.0.1¶
render_pdf()
may take a list of templates or a single template. This restores compatibility with pre-v3.0.0 interface.
v3.0.0¶
get_template_name
has been deprecated in favour ofget_template_names
. This does not affect usages whentemplate_name
is defined.get_download_name
has been deprecated. Overridedownload_name
as a property instead.
v2.2.0¶
django_renderpdf.views.PDFView.url_fetcher
is no longer a static method. If you were overriding this method, make sure you remove the@staticmethod
decorator from your implementation.Improved documentation at RTD.
v2.1.0¶
Add handling of relative URLs. CSS, image files, and other resources will be resolved using Django’s internal URL routing. This includes scenarios like serving static or media files via Django, or serving thing like custom css via custom Django views.
Drop support for Python 3.5.
v2.0.1¶
Improve handling of remote
staticfiles
.
v2.0.0¶
Support Python 3.7 and 3.8.
Support Django 2.2, 3.0 and 3.1.
Drop support for Django < 2.2.
Help¶
If you think you found a bug, or need help with something specific:
Please check existing issues for similar topics.
If there’s nothing relevant, please open a new issue describing your problem, and what you’ve tried so far.
Issues and source code are all in GitHub.
Background¶
django-renderpdf actually started out as code on multiple of my own projects (including some public ones).
After some time, it became clear that I’d been copy-pasting PDF-related bits across different projects, and since co-workers expressed interest in this design (using the Django templating system to generate PDFs), it finally made sense to move this into a separate library.
Donations¶
Donations are welcome. See here for further details.
Licence¶
django-renderpdf is licensed under the ISC licence.