No description
  • Python 96.7%
  • HTML 3.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Sven ed7ad9c43a
Some checks failed
Build and publish / Run tests (push) Successful in 39s
Build and publish / Build and publish (push) Failing after 43s
Create Forgejo releases for version tags
2026-08-26 19:41:09 +02:00
.forgejo/workflows Create Forgejo releases for version tags 2026-08-26 19:41:09 +02:00
bootyprint Changed python version to 3.11+, added initial utility functions for 2025-09-20 18:24:04 +02:00
tests Changed python version to 3.11+, added initial utility functions for 2025-09-20 18:24:04 +02:00
.editorconfig Added template tags; changed PDF_OPTIONS 2025-06-20 16:40:57 +02:00
.gitignore Initial commit 2025-06-19 22:12:48 +02:00
CHANGELOG.md Create Forgejo releases for version tags 2026-08-26 19:41:09 +02:00
conftest.py Added template tags; changed PDF_OPTIONS 2025-06-20 16:40:57 +02:00
LICENSE Initial commit 2025-06-19 22:12:48 +02:00
MANIFEST.in Initial commit 2025-06-19 22:12:48 +02:00
pyproject.toml Create Forgejo releases for version tags 2026-08-26 19:41:09 +02:00
README.md Changed python version to 3.11+, added initial utility functions for 2025-09-20 18:24:04 +02:00
uv.lock Create Forgejo releases for version tags 2026-08-26 19:41:09 +02:00

Django BootyPrint

A Django app for rendering PDF documents with WeasyPrint and BootyPrint.

Installation

pip install django-bootyprint
# or with uv
uv add django-bootyprint

Requirements

  • Python 3.13+
  • Django 5.1.7+
  • WeasyPrint 65.0+

Quick Start

  1. Add 'bootyprint' to your INSTALLED_APPS setting:
INSTALLED_APPS = [
    ...
    'bootyprint',
    ...
]
  1. Customize settings in your settings.py (optional):

See WeasyPrint PDF generation options for the options in PDF_OPTIONS

BOOTYPRINT = {
    'DEFAULT_TEMPLATE': 'myapp/my_template.html',  # Override default template
    'FONT_KITS_STATIC_PATH': 'font_kits',
    'PDF_OPTIONS': {
        'media_type': 'print',
        'pdf_identifier': None,
        'pdf_variant': None,
        'pdf_version': None,
        'pdf_forms': False,
        'uncompressed_pdf': False,
        'custom_metadata': False,
        'srgb': True,
        'optimize_images': True,
        'jpeg_quality': 95,
        'presentational_hints': False,
        'dpi': 96,
        'full_fonts': True,
        'hinting': True,
    },
    'CACHE_ENABLED': True,      # Enable caching (default: True)
    'CACHE_TIMEOUT': 3600,      # Cache timeout in seconds (default: 86400 - 24 hours)
}

Usage

Basic Usage

from bootyprint.utils import generate_pdf
from django.http import HttpResponse

def my_pdf_view(request):
    # Generate PDF from template
    context = {'title': 'My Document', 'content': 'Hello World'}
    pdf_content = generate_pdf(
        template_name='myapp/my_template.html',
        context=context,
        encoding='utf-8'
    )

    # Return as response
    response = HttpResponse(pdf_content, content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="my_document.pdf"'
    return response

Using PDFResponse

from bootyprint.views import PDFResponse
from bootyprint.utils import generate_pdf

def my_pdf_view(request):
    context = {'title': 'My Document', 'content': 'Hello World'}
    pdf_content = generate_pdf(
        template_name='myapp/my_template.html',
        context=context
    )

    return PDFResponse(pdf_content, filename='my_document.pdf')

Using PDFTemplateResponse

from django.views.generic import DetailView
from bootyprint.views import PDFTemplateResponse

def my_pdf_view(request):
    context = {'title': 'My Document', 'content': 'Hello World'}

    return PDFTemplateResponse(
        request=request,
        template='myapp/my_template.html',
        context=context,
        filename='my_document.pdf'
    )

class MyPDFView(DetailView):
    model = MyModel
    template_name = "myapp/my_template.html"
    response_class = PDFTemplateResponse

Template Tags

Load BootyPrint

The latest BootyPrint is included in this library. The bootyprint_css template tag loads it into the html template.

{% load bootyprint %}
<head>
    {% bootyprint_css %}
    <style>
        :root {
            --primary: #3f51b5;
            --secondary: #2196f3;
            --font-size-base: 11px;
            --page-size: A4;
            --page-margin: 10mm;
        }
    </style>
</head>

Local paths to static files

Usually it's the easiest way to provide local, absolute file paths to resources to WeasyPrint. The template tag local_static is like django's static tag, but returns a local path.

{% load bootyprint %}
<img src="{% local_static "img/default_avatar" %}" alt="My Profile Image">

Templates

Bootyprint comes with a default template (bootyprint/default.html) that you can extend or override. Your templates should be valid HTML that WeasyPrint can render to PDF.

Example template:

{% extends "bootyprint/default.html" %}

{% block content %}
<h1>{{ title }}</h1>
<p>{{ content }}</p>

<table>
    <thead>
        <tr>
            <th>Item</th>
            <th>Price</th>
        </tr>
    </thead>
    <tbody>
        {% for item in items %}
        <tr>
            <td>{{ item.name }}</td>
            <td>${{ item.price }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endblock %}

{% block footer %}
    Generated on {{ generation_date|date:"F j, Y" }}
{% endblock %}

License

MIT