python - 如何将 io.BytesIO pdfrw PDF 保存到 Django FileField

标签 python django pdf bytesio pdfrw

我想要做的基本上是:

  • 从 URL 获取 PDF
  • 通过 pdfrw 修改它
  • 将其存储在内存中
    一个 BytesIO 对象
  • 通过以下方式将其上传到 Django FileFieldModel.objects.create(form=pdf_file, name="Some name")

  • 我的问题是,当 create() 方法运行时,它会保存除 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', {})
    

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

    最佳答案

    您可以在代码中使用 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', {})
    

    关于python - 如何将 io.BytesIO pdfrw PDF 保存到 Django FileField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60175556/

    相关文章:

    python - 没有 QLabel 的 QTreeView 中的超链接

    python - Django 上下文不渲染

    Django key 错误

    Django如何将Decimal对象传递给json

    html - 将固定的 HTML 表格转换为相关表格 - 保持尺寸

    javascript - 将 HTML 报告转换为 PDF

    python - 执行多个函数,跟踪是否有返回 true 的函数

    python - 帮助我理解中序遍历而不使用递归

    python - 属性错误 : 'User_Profile' object has no attribute '__name__'

    php - 向现有 PDF 添加边距和裁剪标记