[Answer]-Django forms: attach generated pdf from form values to email

1👍

We use pisa to generate our pdfs. You would do it somewhere between your form.is_valid() and when you attached the pdf to your email.

These three functions were added to our codebase so we can generate pdfs from anywhere.

import os
import StringIO
import xhtml2pdf.pisa as pisa

def fetch_resources(uri, rel):
    """
    Callback to allow xhtml2pdf/reportlab to retrieve Images,Stylesheets, etc.
    `uri` is the href attribute from the html link element.
    `rel` gives a relative path, but it's not used here.
    """
    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:
        path = os.path.join(settings.STATIC_ROOT,
            uri.replace(settings.STATIC_URL, ""))

        if not os.path.isfile(path):
            path = os.path.join(settings.MEDIA_ROOT,
                uri.replace(settings.MEDIA_URL, ""))

            if not os.path.isfile(path):
                raise Exception(
                    'media urls must start with %s or %s' % (
                        settings.MEDIA_ROOT, settings.STATIC_ROOT))

    return path


def render_to_pdf(template_src, context_dict):
    """Function to render html template into a pdf file"""
    template = get_template(template_src)
    context = Context(context_dict)
    html = template.render(context)
    result = StringIO.StringIO()

    pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")),
        dest=result,
        encoding='UTF-8',
        link_callback=fetch_resources)
    if not pdf.err:
        response = HttpResponse(result.getvalue(), mimetype='application/pdf')
        return response

    return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))


def write_pdf(template_src, context_dict, filename):
    template = get_template(template_src)
    context = Context(context_dict)
    html  = template.render(context)
    result = open(filename, 'wb') # Changed from file to filename
    pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")), result)
    result.close()

Leave a comment