初めに
※以下の記事の続きです。未読の場合は先に目を通してください。
【Django】ページをPDF出力する(オプション)【Python】
前回、pdfkitのオプションのcookieにセッションIDを設定することで、
pdfkitのリクエストにセッションIDを持たせられることを確認しました。
これによりセッションで自身とpdfkitの値の受け渡しができるようになりますので、動きを検証します。
注意:この記事は不完全です。最後までお読みください。
環境
名称 | バージョン |
---|---|
Python | 3.10.4 |
Django | 4.0.6 |
pdfkit | 1.0.0 |
検証するページ
前回までpdf出力を行っていたページに、1行だけ出力するボタンを追加しました。
body部は以下のように変更してあります。
値はDBから取得したものを表示し、pdf列の出力ボタン押下時にIDを渡します。
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">pdf</th>
</tr>
</thead>
<tbody>
{% for item in lists %}
<tr>
<th scope="row">{{ item.id }}</th>
<td>{{ item.first_name }}</td>
<td>{{ item.last_name }}</td>
<td>
<form action="to_pdf_alone/" method="post">
{% csrf_token %}
<input type="hidden" value="{{ item.id }}" name="id">
<button type="submit" class="btn btn-success">出力</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<form action="to_pdf/" method="post">
{% csrf_token %}
<button type="submit" class="btn btn-danger">pdf出力</button>
</form>
やりたいこと
ようやくやりたいことの準備が整ったので、ここで目的を明確にします。
これまでの検証は、以下の流れを実現したくて検証していました。
ユーザ操作の選択によってDBアクセスのキーが確定し、それを元に作成されたページをpdf出力したい、というのが重要なポイントです。
---------------------------フロントエンド-------------------------
1.ユーザ操作で出力のボタンが押される
2.選択された対象のPK(今回はID)をバックエンドに渡す
---------------------------バックエンド---------------------------
3.セッションにPKをセットする
4.pdfkitを呼び出す(この際にセッションIDを渡す)
5.pdfkitがセッションからPKを取り出し、PKをキーにDBアクセスする
6.DBから取得した値をフロントに戻す
---------------------------フロントエンド-------------------------
7.1件だけ表示されたページをpdf出力する
セッションで値の受け渡し
pdf列の出力ボタン押下時に呼び出される関数は以下のようになっています。
受け取った値をセッションにセットし、pdfkitにセッションIDを設定して呼び出しています。
def to_pdf_alone(request):
# idを受け取る
id = request.POST.get('id')
# idをセッションにセットする
request.session['id'] = id
url = 'http://127.0.0.1:8000/test_app/detail/'
cookie_list = request.COOKIES
options = {
'cookie': [
('sessionid', cookie_list['sessionid']),
]
}
pdfkit.from_url(url, 'sample.pdf', options=options)
return redirect('test_app:index')
pdfkitに渡されたurlは以下の関数にルーティングされています。
セッションIDを受け取ったpdfkitはセッションから値を取得し、その値でDBアクセスします。
def detail(request):
# idをセッションから受け取る
id = request.session.get('id')
# idをキーにDBアクセス
person = Person.objects.filter(id=id)
context = {'item': {'id': person[0].id, 'first_name': person[0].first_name, 'last_name': person[0].last_name}}
return render(request, 'test_app/detail.html', context)
pdfkitがpdf出力するページは、渡された1件分の値を受け取り表示するだけの簡単なものです。
body部は以下のようになっています。
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">{{ item.id }}</th>
<td>{{ item.first_name }}</td>
<td>{{ item.last_name }}</td>
</tr>
</tbody>
</table>
出力確認
では適当にpdf列のボタンを押下し、出力を確認します。
1件のみの出力が確認できました。
まとめ
今回までで前述の「やりたいこと」内でまとめた流れを実現できました。
これだけのことに記事3つ分も費やしてご苦労様です。疲れてしまいましたね。
ですがこれで思う存分ページをpdf化できます!
...と思っていましたが、pdf列のボタンをポチポチ押して遊んでいてあることに気が付きました。
なんか、出力される値が、遅れてない?