Login

Basic PDF view mixin and utils using reportlab.

Author:
elequ
Posted:
July 19, 2013
Language:
Python
Version:
1.5
Score:
1 (after 1 ratings)

Simplified version of the snippet that renders model to PDF http://djangosnippets.org/snippets/2540/

This PDF view mixin for Django Class Based Views.

See working project example: https://github.com/elena/django-pdfmixin-example


This is based on the case scenario where you have a model which has a DetailView.

You then construct a bespoke PDF for the same model that is unrelated in any way to the DetailView.

The PDF needs to be returned as a HTTPResponse object. The model object is provided.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
""" This is based on the case scenario where you have a model which has a 
`DetailView`, but a "bespoke" PDF for the same model is also created that is 
not dependent on the `DetailView` (except to provide the query object).

The PDF needs to be returned as a `HTTPResponse` object. The model object is 
provided. 

Working project example: https://github.com/elena/django-pdfmixin-example

Credit: For the case scenario to convert HTML pages to PDFs see this snippet
(from which this snippet largely drew upon): 
http://djangosnippets.org/snippets/2540/
"""

## Model

from django.db import models

class Page(models.Model):
    title = models.CharField(max_length=30)
    slug = models.SlugField()
    # ...


## PDF

# -*- coding: utf-8 -*-
from django.http import HttpResponse
from reportlab.pdfgen import canvas

def render_to_pdf(my_page):
    """ https://docs.djangoproject.com/en/dev/howto/outputting-pdf/ """

    response = HttpResponse(content_type='application/pdf')
    # uncomment to toggle: downloading | display (moz browser)
    # response['Content-Disposition'] = 'attachment; filename="myfilename.pdf"'

    c = canvas.Canvas(response)
    c.drawString(100, 600, my_page.title)
    c.showPage
    c.save()
    return response


## URL

# -*- coding: utf-8 -*-
from django.conf.urls import url, patterns
from .views import DetailView

urlpatterns = patterns('',
    url(r'^page/(?P<slug>[\w/-]+)$', DetailView.as_view(),
        name='page_detail'),
)


## View

# -*- coding: utf-8 -*-
from django.views.generic import DetailView
from django.views.generic.base import TemplateResponseMixin

from .models import Page
from .pdfs import render_to_pdf


class PDFResponseMixin(TemplateResponseMixin):
    """
    Mixin for Django class based views.
    Switch normal and pdf template based on request.

    The switch is made when the request has a particular querydict, per
    class attributes, `pdf_querydict_keys` and `pdf_querydict_value`
    example:

        http://www.example.com?[pdf_querydict_key]=[pdf_querydict_value]

    Example with values::

        http://www.example.com?format=pdf

    Simplified version of snippet here:
    http://djangosnippets.org/snippets/2540/
    """
    pdf_querydict_key = 'format'
    pdf_querydict_value = 'pdf'

    def is_pdf(self):
        value = self.request.REQUEST.get(self.pdf_querydict_key, '')
        return value.lower() == self.pdf_querydict_value.lower()

    def get_pdf_response(self, context, **response_kwargs):
        return render_to_pdf(self.get_object())

    def render_to_response(self, context, **response_kwargs):
        if self.is_pdf():
            from django.conf import settings
            context['STATIC_ROOT'] = settings.STATIC_ROOT
            return self.get_pdf_response(context, **response_kwargs)
        #context[self.pdf_url_varname] = self.get_pdf_url()
        return super(PDFResponseMixin, self).render_to_response(
            context, **response_kwargs)


class DetailView(PDFResponseMixin, DetailView):

    model = Page
    slug_field = 'slug'

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 3 months ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 1 week ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 4 weeks ago
  5. Help text hyperlinks by sa2812 11 months, 3 weeks ago

Comments

Please login first before commenting.