Search code examples
djangodjango-modelsdjango-viewsbufferpypdf

Directing Output Paths of Altered Files


How can I direct the destination of the output file to my db?

My models.py is structured like so:

class Model(models.Model):
    char    = models.CharField(max_length=50, null=False, blank=False)
    file    = models.FileField(upload_to=upload_location, null=True, blank=True)

I have the user enter a value for 'char', and then the value of 'char' is printed on to a file. The process of successfully printing onto the file is working, however, the file is outputting to my source directory.

My goal is to have the output file 'pdf01.pdf' output to my db and be represented as 'file' so that the admin can read it.

Much of the information in the Dango docs has been focussed on directing the path of objects imported by the user directly, not on files that have been created internally. I have been reading mostly from these docs:

Models-Fields

Models

File response objects

Outputting PDFs

I have seen it recommend to write to a buffer, not a file, then save the buffer contents to my db however I haven't been able to find many examples of how to do that relevant to my situation online.

Perhaps there is a relevant gap in my knowledge regarding buffers and BytesIO? Here is the function I have been using to alter the pdf, I have been using BytesIO to temporarily store files throughout the process but have not been able to figure out how to use it to direct the output anywhere specific.

        can = canvas.Canvas(BytesIO(), pagesize=letter)
        can.drawString(10, 10, char)
        can.save()
        BytesIO().seek(0)
        text_pdf = PdfFileReader(BytesIO())
        base_file = PdfFileReader(open("media/01.pdf", "rb"))
        page = base_file.getPage(0)
        page.mergePage(text_pdf.getPage(0))
        PdfFileWriter().addPage(page)
        PdfFileWriter().write(open("pdf01.pdf", "wb")

Solution

  • I found this workaround to direct the file to a desired location (in this case both my media_cdn folder and also output it to an admin.)

    I set up an admin action to perform the function that outputs the file so the admin will have access to both the output version in the form of both an HTTP response and through the media_cdn storage.

    Hope this helps anyone who struggles with the same problem.

    #admin.py
    
    class edit_and_output():
    
        def output:
    
            author = Account.email
            #alter file . . .
    
            with open('media_cdn/account/{0}.pdf'.format(author), 'wb') as out_file:
                output.write(out_file)
            response = HttpResponse(content_type='application/pdf')
            response['Content-Disposition'] = 'attachment;filename="{0}.pdf"'.format(author)
            output.write(response)