GET vs POST 차이

HY_1023·2026년 3월 18일

헷갈리는 부분 정리

목록 보기
25/40

HTTP 메서드 완전 기초부터


먼저 GET, POST만 있는 게 아닙니다

실제로는 이런 메서드들이 있어요:

메서드하는 일예시
GET데이터 조회게시글 목록 보기
POST데이터 생성게시글 작성
PUT데이터 전체 수정게시글 전체 교체
PATCH데이터 일부 수정제목만 수정
DELETE데이터 삭제게시글 삭제

그런데 왜 Django에서는 GET/POST만 썼냐?

HTML <form> 태그가 GET, POST만 지원하기 때문입니다

<!-- HTML form은 이 두 가지만 가능 -->
<form method="GET"><form method="POST"><form method="DELETE"> ❌ 브라우저가 지원 안 함

그래서 Django 기초 단계에서는 이렇게 우회했던 거예요:

삭제 → POST /study/3/delete/  (원래는 DELETE 써야 함)
수정 → POST /study/3/update/  (원래는 PUT/PATCH 써야 함)

이미지에서 본 DRF(Django REST Framework)가 나오면?

그때는 모든 메서드를 제대로 사용합니다

GET    /api/posts/      → 목록 조회
POST   /api/posts/      → 새 글 생성
GET    /api/posts/3/    → 3번 글 조회
PUT    /api/posts/3/    → 3번 글 전체 수정
PATCH  /api/posts/3/    → 3번 글 일부 수정
DELETE /api/posts/3/    → 3번 글 삭제

정리하면

Django 기초 (HTML 렌더링)
    → GET, POST만 사용 (폼의 한계)

Django + DRF (API 서버)
    → GET, POST, PUT, PATCH, DELETE 모두 사용
    → 이미지 4번처럼 views를 두 개로 분리하는 이유가 이것!

지금 이미지에서 api_views.pytemplates_views.py 를 나누는 것도 바로 이 차이 때문입니다. API는 모든 메서드를 쓰고, 템플릿은 GET/POST만 쓰니까요.


핵심 차이

GETPOST
용도데이터 조회데이터 전송/저장
데이터 위치URL에 노출Body에 숨겨짐
보안낮음높음
데이터 크기제한 있음제한 없음
캐싱가능불가능

눈으로 보는 차이

# GET - URL에 데이터가 보임
https://example.com/search?keyword=python&page=1

# POST - URL에 데이터가 안 보임
https://example.com/login
(아이디/비밀번호는 숨겨져서 전송)

Django에서 사용 예시

def my_view(request):

    # GET 요청 - 데이터 조회할 때
    if request.method == 'GET':
        posts = Post.objects.all()
        return render(request, 'list.html', {'posts': posts})

    # POST 요청 - 데이터 저장할 때
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            form.save()  # DB 저장

언제 쓰나요?

GET  → 검색, 목록 조회, 상세 보기
POST → 로그인, 회원가입, 게시글 작성, 수정, 삭제

HTML 폼에서

<!-- GET 방식 -->
<form method="GET">
    <input type="text" name="keyword">
</form>

<!-- POST 방식 -->
<form method="POST">
    {% csrf_token %}  <!-- Django 보안 토큰 필수! -->
    <input type="text" name="title">
</form>

💡 조회는 GET, 변경은 POST 로 기억하세요!


질문

from django.shortcuts import get_object_or_404, redirect, render
from .forms import StudyForm
from .models import Study
 
 
def study_list(request):
    studies = Study.objects.all()
 
    total_count = studies.count()
    total_minutes = sum(study.total_minutes for study in studies)
    total_hours = total_minutes // 60
    remain_minutes = total_minutes % 60
 
    context = {
        'studies': studies,
        'total_count': total_count,
        'total_hours': total_hours,
        'remain_minutes': remain_minutes,
    }
    return render(request, 'study/study_list.html', context)
 
 
def study_create(request):
    form = StudyForm(request.POST or None)
 
    if request.method == 'POST' and form.is_valid():
        form.save()
        return redirect('study:list')
 
    return render(request, 'study/study_form.html', {
        'form': form,
        'page_title': '공부 기록 작성',
    })
 
 
def study_detail(request, pk):
    study = get_object_or_404(Study, pk=pk)
    return render(request, 'study/study_detail.html', {
        'study': study,
    })
 
 
def study_update(request, pk):
    study = get_object_or_404(Study, pk=pk)
    form = StudyForm(request.POST or None, instance=study)
 
    if request.method == 'POST' and form.is_valid():
        form.save()
        return redirect('study:detail', pk=study.pk)
 
    return render(request, 'study/study_form.html', {
        'form': form,
        'page_title': '공부 기록 수정',
        'study': study,
    })
 
 
def study_delete(request, pk):
    study = get_object_or_404(Study, pk=pk)
 
    if request.method == 'POST':
        study.delete()
        return redirect('study:list')
 
    return render(request, 'study/study_confirm_delete.html', {
        'study': study,
    })

여기에서 언존헌 석재 흐름이라고 하는데.. post가 왜 안전한  삭제 흐름이니

답변

POST가 안전한 삭제 흐름인 이유

핵심은 "실수로 삭제되는 상황을 막는다" 는 것입니다.


GET으로 바로 삭제하면 생기는 문제

# 만약 GET /study/3/delete/ 로 삭제가 된다면?
  • 브라우저 뒤로가기만 해도 재요청 → 삭제
  • 누군가 링크만 공유해도 클릭한 순간 삭제
  • 브라우저가 페이지 미리 로딩할 때도 삭제
  • <img src="/study/3/delete/"> 같은 태그 하나로도 삭제 가능 (CSRF 공격)

POST 2단계 흐름이 안전한 이유

1단계: GET /study/3/delete/
       → "정말 삭제할까요?" 확인 페이지만 보여줌
       → 아직 아무것도 안 지워짐

2단계: POST /study/3/delete/  (버튼 클릭 시)
       → 그제야 실제 삭제 실행

POST 요청은 폼을 직접 제출해야만 발생하기 때문에:

  • 실수 클릭 → 1단계에서 멈춤 ✅
  • 링크 공유 → 확인 페이지만 열림 ✅
  • 외부 사이트 공격 → Django의 CSRF 토큰이 차단 ✅

코드에서 보면

def study_delete(request, pk):
    study = get_object_or_404(Study, pk=pk)

    if request.method == 'POST':   # POST일 때만 삭제
        study.delete()
        return redirect('study:list')

    # GET이면 → 확인 페이지 렌더링 (삭제 안 함)
    return render(request, 'study/study_confirm_delete.html', {
        'study': study,
    })

즉, 의도를 한 번 더 확인하는 장치가 POST 2단계 흐름의 핵심입니다.


models.py는 Django에서 가장 먼저 작성하는 파일이에요. "DB 테이블의 설계도"라고 생각하면 됩니다. 전체 구조를 단계별로 살펴볼게요.5단계로 나눠서 볼 수 있게 만들었어요. 탭을 클릭하거나 이전/다음 버튼으로 넘겨가면서 보세요.


초보자를 위한 실전 팁 3가지

makemigrations / migrate는 세트다models.py를 수정할 때마다 반드시 두 명령어를 실행해야 DB에 반영됩니다.

python manage.py makemigrations   # 변경사항을 감지해서 설계도 생성
python manage.py migrate          # 실제 DB에 적용

__str__ 는 꼭 써두자 — 없으면 관리자 페이지에서 모든 객체가 Post object (1), Post object (2)... 처럼 보여서 뭐가 뭔지 구분이 안 됩니다.

필드 옵션 두 개만 기억하자blank=True는 폼에서 빈 값 허용, null=True는 DB에서 NULL 허용. 문자열 필드는 blank=True만, 나머지는 null=True, blank=True 함께 씁니다.

궁금한 단계가 있으면 더 깊이 파고들어 드릴게요!

profile
개발언어를 배우는 과정 기록

0개의 댓글