2

このタスクについて、どうしても助けが必要です。1日ハッキングしてきました。この機能は、管理者が管理者インターフェースを介して書いたテキストを、ユーザーが 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

おそらく、save メソッドでネストされたトランザクションが原因でしょうか? しかし、何か基本的なことが欠けている場合や、それを行うための単純な優れた方法がある場合に備えて、これについてより高い助けを求める必要があるように感じます.

どんな助けでも大歓迎です、ありがとう!

4

1 に答える 1

3

これは非常に複雑な方法のようです。この方法により、セーブポイントを作成し、それをDBにコミット/ロールバックしないようにすることができます。これにより、データベースのロックが発生する可能性があります(例のように)。

私はもっ​​と簡単にします-「PDFのプレビュー」ボタンを押すときは、PDFを作成してそれを使用して返すだけです

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

#print PDF to response
return response

これにより、ブラウザにPDFがダウンロードされ、DBに保存されることはありません。プレビューして、すべて問題がないように見えたら、通常の方法で保存します。他のすべての変更をDBに保存するだけなので、ページをリロードしてフォームに保持することができます。

別の解決策は、ステータス= "DRAFT | PUBLISHED"のPDFファイルのファイルステータスフィールドを実装し、ユーザーにPUBLISHEDバージョンのみを表示し、DRAFTは管理者のみで使用できるようにすることです。

于 2012-06-10T08:16:15.790 に答える