6

我想做的基本上是:

  1. 从 URL 获取 PDF
  2. 通过 pdfrw 修改
  3. 将其作为 BytesIO obj 存储在内存中
  4. 通过将其上传到 Django FileField Model.objects.create(form=pdf_file, name="Some name")

我的问题是,当该方法运行时,create()它会保存.form

助手.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

视图.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', {})

如您所见,print()填充 BytesIO 时会给出两个不同的值,这让我相信大小的增加意味着其中实际上有数据。是否有原因无法正确保存到我的 django 模型实例中?另外,如果有人知道更有效的方法来做到这一点,请告诉我!

4

2 回答 2

8

您可以ContentFile在代码中使用类。我在您的视图中进行了相应的修改,以将您的文件保存在文件字段中。

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', {})

您还可以使用该save方法使用类来存储文件ContentFile

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', {})
于 2020-02-14T14:00:22.510 回答
3

这是有关如何将文件保存到对象的文档。

from django.core.files import File

filled_pdf = FilledPDF()
filled_pdf.form.save('test_pdf.pdf', File(submitted_form.getvalue()), save=True)
于 2020-02-14T13:32:18.703 回答