【问题标题】:Django admin "Preview PDF" buttonDjango 管理员“预览 PDF”按钮
【发布时间】:2012-06-10 16:16:15
【问题描述】:

在这项任务上急需帮助;现在已经破解了一天。其功能是将管理员通过管理界面编写的文本翻译成用户可以通过 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 的视图。视图在渲染后删除 doc_copy。

说实话,我认为它是有效的,但现在它给了我一个

TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK

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

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

【问题讨论】:

    标签: python django transactions admin


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 第一个解决方案的问题是我需要在预览 PDF 中提供最新更改,因此我需要在吐出 PDF 但回滚之前“保存”。但是,我确实决定实施第二个建议。每个实例都有一个状态字段,视图表仅呈现“已发布”的 PDF。谢谢!
    猜你喜欢
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 2015-03-27
    • 2018-12-10
    • 2015-01-06
    • 1970-01-01
    相关资源
    最近更新 更多