Django-如何自动创建.docx文件并将其保存到模型&x27;s文件字段?

Django-如何自动创建.docx文件并将其保存到模型&x27;s文件字段?,django,Django,这是我的用例。我有一个租赁合同模板(.docx文件)。我希望通过从模型中提取数据并将其注入模板(使用Jinja标记)来填充此合同的字段,然后将输出文件直接保存到数据库中。到目前为止还不错 我的问题是,我目前的做法是分两步进行的;1) 打开模板,填充并另存为新文件;2) 将文件作为文件字段上载到我的模型,从而创建副本 有没有一种方法可以让我在不保存格式化文件的情况下创建和存储格式化文件?(从而避免重复) 根据这一点,建议的方法是使用django.core.files.base.ContentFil

这是我的用例。我有一个租赁合同模板(.docx文件)。我希望通过从模型中提取数据并将其注入模板(使用Jinja标记)来填充此合同的字段,然后将输出文件直接保存到数据库中。到目前为止还不错

我的问题是,我目前的做法是分两步进行的;1) 打开模板,填充并另存为新文件;2) 将文件作为文件字段上载到我的模型,从而创建副本

有没有一种方法可以让我在不保存格式化文件的情况下创建和存储格式化文件?(从而避免重复)

根据这一点,建议的方法是使用
django.core.files.base.ContentFile
并将文件内容作为字符串传递,如下所示

self.lease_draft.save("Name of the file", ContentFile("A string with the file content"))
我的问题是ContentFile()只接受字符串或字节作为参数。我的输入是一个填充的.docx文件(DocxTemplate对象),而不是字符串

关于如何处理这个问题有什么建议吗

型号.py

class Booking(models.Model):
    lease_draft = models.FileField(upload_to='lease_drafts/', null=True)
from django.core.files.base import ContentFile
from docxtpl import DocxTemplate

def populate_docx(self, template_path, context):

        draft_lease = DocxTemplate(template_path) /// Gets the template
        draft_lease.render(context) /// Populates the template

        self.lease_draft.save('Lease #12345', ContentFile(draft_lease)) /// Save the populated file (throws an error)
视图.py

class Booking(models.Model):
    lease_draft = models.FileField(upload_to='lease_drafts/', null=True)
from django.core.files.base import ContentFile
from docxtpl import DocxTemplate

def populate_docx(self, template_path, context):

        draft_lease = DocxTemplate(template_path) /// Gets the template
        draft_lease.render(context) /// Populates the template

        self.lease_draft.save('Lease #12345', ContentFile(draft_lease)) /// Save the populated file (throws an error)
错误

TypeError: a bytes-like object is required, not 'DocxTemplate'

我假设您使用的是docxtpl和pythondocx。docx可以以字节形式保存对象。
像这样的方法应该会奏效:

import io
def populate_docx(self, template_path, context):
        
        draft_lease = DocxTemplate(template_path) /// Gets the template
        draft_lease.render(context) /// Populates the template
        file_bytes = io.BytesIO()
        draft_lease.save(file_bytes)
        file_bytes.seek(0)
        self.lease_draft.save('Lease #12345', ContentFile(file_bytes.read()))