Djangoでは HttpResponse の status に整数を指定してHTTPステータスコードを返します。JSON APIの応答と、Http404を投げてHTMLエラーハンドラーへ渡す処理は別です。
| この記事の要点 |
|---|
|
|
from django.http import HttpResponse from django.views.generic import View def get(self, request, *args, **kwargs): response = HttpResponse(status=401) return response |
HttpResponseのstatusにステータスコードを渡してreturnすればOK
404を返すこととHttp404を投げることの違い
return HttpResponse("Missing", status=404) や HttpResponseNotFound("Missing") は、そのレスポンスを直接返します。handler404 は呼ばれません。raise Http404 は例外経路へ渡し、DEBUG=False ならルートURLconfの handler404、未指定なら既定の404ビューが本文を作ります。URLに一致するパターンがない場合も404の処理へ進みます。
DEBUG=True では404用の技術情報画面になるため、独自404画面の確認は DEBUG=False と適切な ALLOWED_HOSTS で行います。返すだけの404や明示したJSONは、この切替で自動的に別形式になりません。例外の詳細・入力値をそのまま本文へ出さないでください。
JSON APIは本文形式も明示する
JsonResponse({"error": "not_found"}, status=404) は application/json の本文を返します。status=404 だけではJSONになりません。また通常のDjangoの404ハンドラーは Accept: application/json を付けただけでJSONへ切り替わるわけではありません。APIのエラー形式はそのAPI側で統一し、HTML用ハンドラーと分けて設計します。
旧表のDRF例は、別途 Django REST framework を導入した APIView / @api_view 等の処理内で使うものです。通常のDjangoビューに Response だけを移す例ではありません。下の検証例はDjango標準の JsonResponse だけを使い、DRFのレンダラー・認証は検証していません。
204・304・HEADでは本文を送らない
| 応答 | 使い方と境界 |
|---|---|
| 204 No Content | HttpResponse(status=204) のように本文なしで返す。JSONの成功データを載せたいなら、API仕様に合う200等を選ぶ。 |
| 304 Not Modified | 条件付きGET/HEADの条件判定後に使う。HttpResponseNotModified は本文を受け付けない。単に本文がない成功応答の代わりには使わない。 |
| HEAD | GETに相当するヘッダーを返すが本文は送らない。Viewの既定ではget実装がheadにも利用される。処理が実行されない・副作用が起きないという意味ではない。 |
HttpResponse("text", status=204) というオブジェクト自体には本文を保持できてしまいます。Django Client は204・304・HEADの本文を除去してからテストへ返します。オブジェクトの content が空であることと送信境界を混同せず、最初から本文を付けない実装にします。実サーバー・プロキシでの送信挙動をClientだけで検証したことにはなりません。下の304は固定ヘッダーの検体で、条件判定やキャッシュ制御の完成実装ではありません。
405とAllowヘッダー
HttpResponseNotAllowed(["GET", "HEAD"]) は405と Allow: GET, HEAD を返します。単なる HttpResponse(status=405) では許可メソッド一覧を自動生成しません。クラスベースの View では、未実装メソッドに405を返し、getがあれば通常HEADも扱い、既定のOPTIONSも Allow に含まれます。許可一覧は実際に提供するメソッドと合わせます。CSRF検査が先に拒否すれば、POSTで405ではなく403になる場合もあります。
認証・権限・CSRFを混同しない
PermissionDenied は通常403の例外処理へ進みますが、401/403を返すだけでは利用者の認証や権限判定は実施されません。Djangoの login_required は未ログインなら通常ログイン画面へリダイレクトします。HTMLログインとAPIの認証エラー契約を分けてください。CSRF失敗は既定で403ですが、PermissionDenied の handler403 ではなく CSRF_FAILURE_VIEW で扱います。JSON応答を選んでもCSRF・認証・入力検証が不要になるわけではありません。
独自ハンドラーの最小例
ルートURLconfで handler400 / handler403 / handler404 / handler500 を指定します。400・403・404の関数は (request, exception)、500は (request) を受け取ります。エラー画面の本文を作っても status を省くと200になり得るので、各応答に正しい状態を明示します。DEBUG=True では400・404・500の独自ハンドラーは技術情報画面に置き換わりますが、403まで同じ切替と考えないでください。
次は単独のURLconfとして読み込める例です。各レスポンスは固定値で、DB・外部通信・実資格情報は使いません。認証や情報漏えい防止を保証する構成ではなく、実アプリのエラー処理・認可・ログの安全性は別途確認が必要です。
"""Fixed responses only; no database, credentials, or external services."""
from django.core.exceptions import PermissionDenied, SuspiciousOperation
from django.http import (
Http404, HttpResponse, HttpResponseNotAllowed, HttpResponseNotModified,
JsonResponse,
)
from django.urls import path
from django.views.generic import View
def direct_404(request):
return HttpResponse("<p>Missing</p>", status=404)
def raised_404(request):
raise Http404("Synthetic missing item")
def api_missing(request):
return JsonResponse({"error": "not_found"}, status=404)
def no_content(request):
return HttpResponse(status=204)
def not_modified(request):
# Use only after evaluating a real conditional request in an application.
return HttpResponseNotModified(headers={"ETag": '"demo-v1"'})
def method_limited(request):
if request.method not in {"GET", "HEAD"}:
return HttpResponseNotAllowed(["GET", "HEAD"])
return HttpResponse("Readable")
class ReadView(View):
def get(self, request, *args, **kwargs):
return HttpResponse("Readable")
def forbidden(request):
raise PermissionDenied
def bad_request(request):
raise SuspiciousOperation("Synthetic invalid request")
def server_error(request):
raise RuntimeError("Synthetic failure")
def csrf_probe(request):
return HttpResponse("No write performed")
def error400(request, exception):
return HttpResponse("<p>Bad request</p>", status=400)
def error403(request, exception):
return HttpResponse("<p>Forbidden</p>", status=403)
def error404(request, exception):
return HttpResponse("<p>Custom missing</p>", status=404)
def error500(request):
return HttpResponse("<p>Server error</p>", status=500)
# These assignments belong in the project's ROOT URLconf, not an included URLconf.
handler400 = error400
handler403 = error403
handler404 = error404
handler500 = error500
urlpatterns = [
path("direct/", direct_404),
path("raised/", raised_404),
path("api/", api_missing),
path("empty/", no_content),
path("cached/", not_modified),
path("method/", method_limited),
path("class/", ReadView.as_view()),
path("forbidden/", forbidden),
path("bad/", bad_request),
path("failure/", server_error),
path("csrf/", csrf_probe),
]
確認環境と公式資料
2026年10月26日、Python 3.12.10 / Django 5.2.18 の独立した合成settingsで、Django Clientによる状態・本文・ヘッダーと DEBUG の差を検証しています。実ネットワーク・DB・本番認証・配備環境のテストではありません。エラーのログ設計はログ出力方法、実環境でのみ起きる問題は本番環境へのデプロイも参照してください。
- Django公式:HttpResponse・JsonResponse・応答のサブクラス
- Django公式:Http404とエラーハンドラー
- Django公式:ルートURLconfのhandler指定
- Django公式:ClientとRequestFactory
- Django公式:CSRF失敗時の処理
- Django公式:login_required
- DRF公式:status付きResponse
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスのソフト一覧|Blender・Metasequoiaと用途別の選び方
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Visual Studio「デザイナーを表示できません」エラーの原因と対処 2026-10-28 12:06:00
- SSH 認証に失敗しました。再試行してください の対処 2026-10-28 12:06:00
- SSH2 秘密鍵の読み込みに失敗しました の原因と対処 2026-10-28 12:06:00
- TeraTerm のよくあるエラーと対処法完全ガイド — Connection refused / 2026-10-28 12:06:00
- Visual Studio エラー一覧|コンパイルエラー・警告の確認方法と対処 2026-10-28 11:39:57
- Whitelabel Error Page の原因と消し方|Spring Boot のエラーページ 2026-10-28 11:39:57
- Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法 2026-10-28 11:39:57
- SQL WHERE 句完全ガイド 2026-10-28 11:39:57
- SQL JOIN 完全ガイド (INNER/LEFT/RIGHT/FULL OUTER) 2026-10-28 11:39:57
- tomcat の起動 / 停止ログと catalina.log・catalina.out の違い 2026-10-28 10:24:23
- Tomcat の起動確認方法 5 つ|localhost:8080・ポート・プロセス・ログ 2026-10-28 10:24:23
- Oracle 19c COMMITの使い方: 暗黙コミット・自動確定・応答不明時の確認 2026-10-28 09:59:09
- Oracle 19c DELETE文|削除対象の確認・COMMIT前の判断・ROLLBACKの条件 2026-10-28 09:59:09
- Oracle 19c INSERT文|INSERT ALL・SELECT・RETURNINGとMERGEの使い分け 2026-10-28 09:59:09
- Oracle 19cのトランザクション制御|COMMIT・ROLLBACK・分離レベルと接続設定 2026-10-28 09:59:09