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))