Django における HTTP リクエストデータの取得方法:request.POST.get() と form_data["key"] の違いを理解する
はじめに
新卒研修でタスク管理アプリを開発している際に、確認画面を挟んだフォーム送信の実装で request.POST.get() と form_data["key"] の使い分けに迷いました。
どちらも「フォームのデータを取得する」処理のように見えますが、実は 取得元 が大きく異なります。今回は実際のコードを交えながら、Django 初学者の方に向けてこの 2 つの違いを解説します。
環境
- Python 3.14.3
- Django 5.2
- SQLite3
今回関係するファイル構成
task/
├── views.py ← request.POST.get() はここ
└── templates/
└── task/
├── create.html ← 入力フォーム
└── create_confirm.html ← form_data を参照するのはここ
views.py でブラウザからデータを受け取り、create_confirm.html で確認画面を表示するという 2 ステップの流れを軸に解説します。
そもそも何が違うのか
結論として、両者には以下の違いがあります。
| 比較項目 | request.POST.get() |
form_data["key"] |
|---|---|---|
| 取得元 | Django が POST リクエストからパースしたフォームデータ | Python の辞書オブジェクト |
| キーが存在しない場合 | None を返す(エラーにならない) |
KeyError が発生する |
| どこで使うか | ブラウザから POST されたデータを取得する時 | 一度辞書に格納したデータを参照する時 |
| 実行順序 | 先に実行する必要がある | 辞書を作成した後でないと使えない |
重要:実行順序がある
本記事の実装では、form_data という辞書は request.POST.get() で取得した値を格納して作成しているため、辞書を作成した後でなければ参照できません。実際のコードで確認します。
① request.POST.get() で HTTP リクエストから直接取得する
# task/views.py の task_create より抜粋
@login_required
def task_create(request):
if request.method == 'POST':
form_data = {
'title': request.POST.get('title'), # ← HTTP リクエストから直接取得
'description': request.POST.get('description'),
'team_id': request.POST.get('team_id'),
'assignee_id': request.POST.get('assignee_id') or '',
'priority': request.POST.get('priority'),
'status': request.POST.get('status'),
'start_date': request.POST.get('start_date'),
'due_date': request.POST.get('due_date'),
}
この時点で request.POST.get() が実行され、その戻り値が辞書 form_data に格納されます。
② 辞書に格納した後であれば form_data["key"] で参照できる
# ① の直後 — form_data が完成しているため参照できる
return render(request, 'task/create_confirm.html', {
'form_data': form_data, # ← テンプレートに渡す
})
テンプレート側では {{ form_data.title }} として表示できます。
③ ❌ 別リクエストでは前の form_data にアクセスできない
確認画面から「登録する」ボタンを押すと、新しい HTTP リクエスト が発生します。Django のビュー関数内のローカル変数 form_data はリクエストごとに生成され、処理が終わると破棄されます。そのため、別のリクエストを処理するビュー関数からは参照できません。
以下のように form_data['title'] を使おうとすると、実際にこのエラーが発生しました。
# ❌ 悪い例:task_create で作った form_data に別リクエストからアクセスしようとした場合
title = form_data['title']

また、辞書に存在しないキーへ .get() を使わずにアクセスした場合も同様にエラーになります。
# ❌ 悪い例:存在しないキーに直接アクセス
print(form_data['存在しないキー'])

✅ 正しい書き方:task_create_confirm では改めて request.POST.get() で取得します。
# task/views.py の task_create_confirm より抜粋
@login_required
def task_create_confirm(request):
if request.method == 'POST':
TaskManager.create_task(
title = request.POST.get('title'), # ← 再び HTTP リクエストから取得
description = request.POST.get('description'),
...
)
request.POST.get() とは
request.POST.get() は、ブラウザから POST 送信されたフォームデータを取得するための処理です。厳密には HTTP リクエストボディそのものを直接読んでいるのではなく、Django がフォームデータをパースして request.POST というオブジェクトに格納したものから値を取得しています。
def task_create_confirm(request):
if request.method == 'POST':
title = request.POST.get('title') # ブラウザから送信された title を取得
description = request.POST.get('description')
ブラウザからサーバーへのデータの流れはこのようになっています。
ブラウザ
↓ フォームを submit(POST リクエスト)
HTTP リクエストボディ: title=教材スライド作成&description=...
↓
Django がフォームデータをパース
↓
request.POST = {'title': '教材スライド作成', 'description': '...'}
↓
request.POST.get('title') → '教材スライド作成'
.get() メソッドを使うことで、キーが存在しない場合は None を返すため安全に取得できます。
# キーが存在しない場合
request.POST.get('存在しないキー') # → None(エラーにならない)
request.POST['存在しないキー'] # → KeyError が発生
form_data["key"] とは
Python のコード内で作成した辞書オブジェクトからデータを取得します。
# request.POST から取得した値を辞書にまとめる
form_data = {
'title': request.POST.get('title'),
'description': request.POST.get('description'),
'priority': request.POST.get('priority'),
'status': request.POST.get('status'),
}
重要なのは、form_data の中身は もともと request.POST.get() で取得した値 だということです。
form_data = {
'title': request.POST.get('title'), # ← 結局は POST から取得している
}
form_data['title'] # → request.POST.get('title') と同じ値
実際のコードで見る流れ
【入力画面】
ブラウザ → POST 送信
↓
request.POST.get('title') ← HTTP リクエストから取得 ★ここが先
↓
form_data = {'title': '...'} ← 辞書に格納 ★これが後
↓
確認画面に渡す(form_data はここで役目を終える)
【確認画面】
{{ form_data.title }} で表示
↓
hidden フィールドに値を埋め込む
<input type="hidden" name="title" value="{{ form_data.title }}">
↑ これがあるから、登録ボタンを押したときに title が POST データとして送られる
【登録処理】
ブラウザ → POST 送信(2回目・別リクエスト)
↓
request.POST.get('title') ← hidden フィールドの値を HTTP リクエストとして受け取る
※ form_data['title'] は使えない(前のリクエストのローカル変数のため)
↓
データベースに保存
セッションとの違い
# セッション(ログイン状態など、リクエストをまたいで保持)
request.session['user_id'] = user['id'] # ログイン時にセット
user_id = request.session.get('user_id') # 別のリクエストでも取得できる
# POST(フォームから送信されたデータ、そのリクエスト限りで消える)
title = request.POST.get('title') # このリクエスト中のみ有効
| 種類 | 保持期間 | 用途 |
|---|---|---|
request.POST |
リクエスト中のみ | フォーム送信データ |
request.GET |
リクエスト中のみ | URL パラメータ |
request.session |
セッション有効期限まで(ログアウト・タイムアウト・有効期限切れなど) | ログイン状態・ユーザー情報 |
まとめ
request.POST.get() |
form_data["key"] |
|
|---|---|---|
| 取得元 | Django が POST リクエストからパースしたフォームデータ | Python の辞書 |
| タイミング | ブラウザから POST を受け取った直後 | 辞書に格納した後 |
| 実行順序 | 先に実行する必要がある | 辞書を作成した後でないと使えない |
| 関係性 | form_data の中身の元になる |
request.POST.get() の値を格納したもの |
重要なポイントは、form_data["title"] の中身は最終的に request.POST.get('title') で取得した値だということです。form_data は一時的な入れ物であり、request.POST.get() なしには成立しないという点です。
今回の開発を通じて、HTTP リクエストと Python オブジェクトの違いを意識することの大切さを改めて実感しました。
クラスメソッドオペレーションズ株式会社について
クラスメソッドグループのオペレーション企業です。
運用・保守開発・サポート・情シス・バックオフィスの専門チームが、IT・AIをフル活用した「しくみ」を通じて、お客様の業務代行から課題解決や高付加価値サービスまでを提供するエキスパート集団です。
当社は様々な職種でメンバーを募集しています。
「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、クラスメソッドオペレーションズ株式会社 コーポレートサイトをぜひご覧ください。
※2026年1月 アノテーション㈱から社名変更しました。







