Skip to main content
 首页 » 编程设计

python之Django 管理员 "Preview PDF"按钮

2024年08月30日32qq号

在此任务上迫切需要帮助;现在已经砍了一天了。该功能是将管理员通过管理界面编写的文本翻译成用户可以通过 Web 应用程序查看的 PDF。

该功能已实现,但我希望能够在实际发布之前看到我将生成的 PDF。所以在管理界面中,我希望创建一个“预览 PDF”按钮。本质上,它会保存当前表单(带有新更改)生成 PDF,以便可以看到更改,并回滚到原始状态,这样外界就看不到任何更改。

我正在通过覆盖模型中的保存功能来解决这个问题。

@transaction.commit_manually 
def save(self, force_insert=False, force_update=False, using=None): 
    super(Doc, self).save(force_insert=force_insert, force_update=force_update, using=using) 
    if self.preview: 
        from lava_server.settings import common 
        # make a copy 
        doc_copy = self 
        doc_copy.id = None 
        # Prevent loopback 
        doc_copy.preview = False 
        transaction.rollback() 
        doc_copy.save() 
        common.TEMP_PDF_ID = doc_copy.id 
    else: 
        transaction.savepoint_commit(sid) 

我还覆盖了 response_change 和 response_add 以重定向到呈现 PDF 的 View 。 View 在呈现后删除 doc_copy。

老实说,我认为它在工作,但现在它给了我一个

TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK 

可能是因为我在save方法中嵌套了事务?但我觉得我应该在这方面寻求更高的帮助,以防我遗漏了一些基本的东西,或者只有一种简单的更好的方法。

非常感谢任何帮助,谢谢!

请您参考如下方法:

这似乎是一种非常复杂的方法 - 这样您就可以创建一个保存点并且永远不会将其提交/回滚到数据库中,这可能会导致数据库锁定(就像您的示例中一样)。

我会做得更简单 - 当点击“预览 PDF”按钮时,只需创建 pdf 并使用

response = HttpResponse(mimetype='application/pdf') 
response['Content-Disposition'] = 'attachment; filename=preview.pdf' 
 
#print PDF to response 
return response 

这将在您的浏览器中下载 PDF,并且不会保存到数据库中。您可以预览它,当一切正常时 - 然后以常规方式保存它。只需将所有其他更改保存在数据库中,以便在重新加载页面时将它们保留在表单中。

另一种解决方案是为 PDF 文件实现文件状态字段,状态为“DRAFT|PUBLISHED”,并仅向用户显示 PUBLISHED 版本,而 DRAFT 仅在管理员中可用...