🔧 Django에서 HTML 폼으로 DELETE 요청 처리하기 — Middleware 활용법
✅ 문제 상황
HTML 폼(<form>)은 GET과 POST 메서드만 지원합니다. 그러나 RESTful 원칙에 따르면, 삭제 작업은 DELETE 메서드를 사용하는 것이 적절합니다.
즉, HTML 폼으로는 다음과 같은 코드는 작동하지 않습니다:
<form method="DELETE"> <!-- ❌ 동작하지 않음 -->
✅ 해결 방법 1: POST 방식 + 숨은 필드 우회
HTML에서는 method="POST"로 고정한 뒤, 숨은 필드로 원하는 메서드를 명시합니다.
📌 HTML 예시
<form action="/shorten/{{ code }}/" method="POST">
{% csrf_token %}
<input type="hidden" name="_method" value="DELETE">
<button type="submit">삭제</button>
</form>
📌 View 처리 예시
if request.method == "POST" and request.POST.get('_method') == "DELETE":
# 삭제 처리
obj = get_object_or_404(MyModel, pk=pk)
obj.delete()
return redirect("/")
이 방식은 단순하고 빠르지만, view마다 _method를 직접 확인해야 하므로 중복 코드가 생깁니다.
✅ 해결 방법 2: Middleware로 자동 처리
숨은 필드를 통해 전달된 _method 값을 기반으로, 요청 메서드를 강제로 변경하는 미들웨어를 설정하면 view에서는 신경 쓸 필요가 없습니다.
📌 Middleware 코드 예시 (middleware/http_method_override.py)
class MethodOverrideMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.method == "POST":
override_method = request.POST.get("_method")
if override_method:
request.method = override_method.upper()
request._load_post_and_files()
request.META["REQUEST_METHOD"] = override_method.upper()
return self.get_response(request)
📌 settings.py에 등록
MIDDLEWARE = [
# ...
'yourproject.middleware.http_method_override.MethodOverrideMiddleware',
# ...
]
✅ Middleware가 뭐길래?
Middleware는 Django의 HTTP 요청/응답 흐름을 가로채서 특정 로직을 선처리(pre-processing)하거나 후처리(post-processing)할 수 있는 훅(hook)입니다.
기능 예시
요청 조작 | 요청 메서드 바꾸기, 사용자 인증 체크 등 |
응답 가공 | 응답 헤더 추가, 로깅 처리 등 |
✅ 실전 팁
- 이 미들웨어는 PUT, PATCH도 함께 처리할 수 있도록 확장 가능합니다.
- CSRF 보호는 그대로 유지되므로 보안 문제는 없습니다.
- JavaScript 없이도 RESTful한 구조를 유지할 수 있다는 장점이 있습니다.
✅ 요약
방법 특징
POST + _method | 간단하지만 view마다 분기 필요 |
Middleware 방식 | 전역 처리 가능, view는 원래처럼 작성 가능 |
Django 프로젝트에서 RESTful 구조를 유지하면서 HTML 폼만으로 DELETE 요청을 구현하고 싶을 때 매우 유용한 패턴입니다 ✅
'기술블로그-Django편' 카테고리의 다른 글
🔍 Django ORM Field Lookups 완벽 정리 (0) | 2025.05.14 |
---|---|
🔍 Django ORM: get() vs filter() 차이점 완벽 정리 (0) | 2025.05.14 |
🔄 Django에서 access_count += 1 vs F("access_count") + 1 완전 비교 (0) | 2025.05.14 |
[Django 3일차] Django에서의 요청(request)과 뷰(view)의 모든 것 1/4 (short_url 프로젝트)(250514) (0) | 2025.05.14 |
🔍 Django에서 Model.objects.get(code=code)가 뭔 뜻이야? (0) | 2025.05.14 |