Search code examples
djangoxhtml2pdf

Django - writing a PDF created with xhtml2pdf to server's disk


I'm trying to write a script that will save a pdf created by xhtml2pdf directly to the server, without doing the usual route of prompting the user to download it to their computer. Documents() is the Model I am trying to save to, and the new_project and output_filename variables are set elsewhere.

            html = render_to_string(template, RequestContext(request, context)).encode('utf8')
            result = open(output_filename, "wb")
            pdf = CreatePDF(src=html, dest=results, path = "", encoding = 'UTF-8', link_callback=link_callback) #link callback was originally set to link_callback, defined below
            result.close()
            if not pdf.err:

                new_doc=Documents()
                new_doc.project=new_project
                new_doc.posted_by=old_mess[0].from_user_fk.username
                new_doc.documents = result
                new_doc.save()

With this configuration when it reaches new_doc.save() I get the error: 'file' object has no attribute '_committed'

Does anyone know how I can fix this? Thanks!


Solution

  • After playing around with it I found a working solution. The issue was I was not creating the new Document while result (the pdf) was still open.

    "+" needed to be added to open() so that the pdf file was available for reading and writing, and not just writing.

    Note that this does save the pdf in a different folder first (Files). If that is not the desired outcome for your application you will need to delete it.

                html = render_to_string(template, RequestContext(request, context)).encode('utf8')
                results = StringIO()
                result = open("Files/"+output_filename, "w+b")
                pdf = CreatePDF(src=html, dest=results, path = "", encoding = 'UTF-8', link_callback=link_callback) #link callback was originally set to link_callback, defined below
    
                if not pdf.err:
                    result.write(results.getvalue())
                    new_doc=Documents()
                    new_doc.project=new_project
                    new_doc.documents.save(output_filename, File(result))
                    new_doc.posted_by=old_mess[0].from_user_fk.username
    
                    new_doc.save()
                result.close()