Django における HTTP リクエストデータの取得方法:request.POST.get() と form_data["key"] の違いを理解する

Django における HTTP リクエストデータの取得方法:request.POST.get() と form_data["key"] の違いを理解する

2026.06.26

はじめに

新卒研修でタスク管理アプリを開発している際に、確認画面を挟んだフォーム送信の実装で 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']

NameError: name 'form_data' is not defined

また、辞書に存在しないキーへ .get() を使わずにアクセスした場合も同様にエラーになります。

# ❌ 悪い例:存在しないキーに直接アクセス
print(form_data['存在しないキー'])

KeyError: '存在しないキー'

正しい書き方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月 アノテーション㈱から社名変更しました。

この記事をシェアする

関連記事