What I am trying to do is basically:
Model.objects.create(form=pdf_file, name="Some name")
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', {})
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!
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', {})
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', {})
Here's the documentation on how to save a file to an object.
from django.core.files import File
filled_pdf = FilledPDF()
filled_pdf.form.save('test_pdf.pdf', File(submitted_form.getvalue()), save=True)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With