如何将io.BytesIO pdfrw PDF保存到Django FileField中 [英] How to Save io.BytesIO pdfrw PDF into Django FileField
问题描述
我想做的基本上是:
- 从URL获取PDF
- 通过pdfrw对其进行修改
- 将其存储在内存中BytesIO obj
- 通过以下方式将其上传到Django FileField中
Model.objects.create(form = pdf_file,name ="Some name")
我的问题是,当 create()
方法运行时,它将为 form
保存所有 except 字段.
My issue is that when the create()
method runs, it saves all of the fields except for the form
.
helpers.py
import io
import tempfile
from contextlib import contextmanager
import requests
import pdfrw
@contextmanager
def as_file(url):
with tempfile.NamedTemporaryFile(suffix='.pdf') as tfile:
tfile.write(requests.get(url).content)
tfile.flush()
yield tfile.name
def write_fillable_pdf(input_pdf_path, output_pdf_path, data_dict):
template_pdf = pdfrw.PdfReader(input_pdf_path)
## PDF is modified here
buf = io.BytesIO()
print(buf.getbuffer().nbytes). # Prints "0"!
pdfrw.PdfWriter().write(buf, template_pdf)
buf.seek(0)
return buf
views.py
from django.core.files import File
class FormView(View):
def get(self, request, *args, **kwargs):
form_url = 'http://some-pdf-url.com'
with as_file(form_url) as temp_form_path:
submitted_form = write_fillable_pdf(temp_form_path, temp_form_path, {"name": "John Doe"})
print(submitted_form.getbuffer().nbytes). # Prints "994782"!
FilledPDF.objects.create(form=File(submitted_form), name="Test PDF")
return render(request, 'index.html', {})
如您所见,在填充BytesIO时, print()
给出两个不同的值,使我相信大小的增加意味着其中实际上有数据.是否有没有将其正确保存到我的Django模型实例中的原因?另外,如果有人知道更有效的方法,请告诉我!
As you can see, print()
gives out two different values as the BytesIO is populated, leading me to believe the increase in size means there is actually data in it. Is there a reason it is not saving properly into my django model instance? Also, if anyone knows a more efficient way to do this, please let me know!
推荐答案
您可以在代码中使用 ContentFile
类.我在您的视图中做了相应的修改,以将文件保存在文件字段中.
You can use ContentFile
class in your code. I did modification accordingly in your view to save your file in filefield.
from django.core.files.base import ContentFile
class FormView(View):
def get(self, request, *args, **kwargs):
form_url = 'http://some-pdf-url.com'
with as_file(form_url) as temp_form_path:
submitted_form = write_fillable_pdf(temp_form_path, temp_form_path, {"name": "John Doe"})
pdf_content = ContentFile(submitted_form.getvalue(), 'sample.pdf')
FilledPDF.objects.create(form=pdf_content, name="Test PDF")
return render(request, 'index.html', {})
您还可以通过 ContentFile
类使用 save
方法存储文件.
You can also use the save
method to store file using the ContentFile
class.
from django.core.files.base import ContentFile
class FormView(View):
def get(self, request, *args, **kwargs):
form_url = 'http://some-pdf-url.com'
with as_file(form_url) as temp_form_path:
submitted_form = write_fillable_pdf(temp_form_path, temp_form_path, {"name": "John Doe"})
pdf_content = ContentFile(submitted_form.getvalue())
filled_pdf = FilledPDF()
filled_pdf.name = "Test PDF"
filled_pdf.form.save("sample.pdf", pdf_content, save=False)
filled_pdf.save()
return render(request, 'index.html', {})
这篇关于如何将io.BytesIO pdfrw PDF保存到Django FileField中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!