Home > OS >  How to add PDF file created with BytesIO into a FileField in a model of Django
How to add PDF file created with BytesIO into a FileField in a model of Django

Time:10-20

I can create a PDF file using reportlab in a Django application. However, I can't add it into a FileField in a model. I wonder how to transfer an io.BytesIO data into FileField in Django.

This is summary of my views.py.

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
from reportlab.pdfbase import pdfmetrics

buffer = io.BytesIO()
cc = canvas.Canvas(buffer, pagesize=A4)

# describe something
font_name = "HeiseiKakuGo-W5"
cc.registerFont(UnicodeCIDFont(font_name))
cc.setFont(font_name, 7)
cc.drawString(65*mm, 11*mm, 'test')

cc.showPage()
cc.save()
buffer.seek(0)

exampleObject= get_object_or_404(SomeModel, pk=self.kwargs['pk'])
exampleObject.exampleFileField.save('test.pdf', File(buffer)) # here! this sentence doesn't work.
exampleObject.save()

return FileResponse(buffer, as_attachment=True, filename='test.pdf')

The point is the sentence below doesn't work. I think "File(buffer)" is not appropliate.

exampleObject.exampleFileField.save('test.pdf', File(buffer))

Although once I tried to save a pdf into a FileField after creating a pdf file in a directory as a temporaly file, I prefer to do it by using io.BytesIO.

CodePudding user response:

You may need to seek(0) on your buffer, since it's been used previously, I wouldn't be surprised the buffer would be at the end and result in an empty file saved in Django.

CodePudding user response:

I believe your missing buffer.get_value()

I also use ContentFile instead of File though not sure it's necessary.

I just tested the following snippet and it works using reportlab==3.5.32

import io

from django.core.files.base import ContentFile
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas

from my_app.models import MyModel

buffer = io.BytesIO()
canv = canvas.Canvas(buffer, pagesize=A4)
canv.drawString(100, 400, "test")
canv.save()
pdf = buffer.getvalue()
buffer.close()

my_object = MyModel.objects.latest("id")
my_object.file_field.save("test.pdf", ContentFile(pdf))

  • Related