Django 프론트& 백엔드 개발

Model 단계에서의 유효성 검사

Data Jun 2026. 1. 11. 11:06

웹 애플리케이션에서 가장 흔하게 발생하는 문제 중 하나는 **“잘못된 데이터가 그대로 저장되는 것”**입니다.

  • 이미 존재하는 제목을 또 저장하거나
  • 길이가 초과된 문자열이 들어오거나
  • 사용자가 필수 입력값을 비워둔 채 제출하는 상황

이런 문제를 매번 직접 if 문으로 처리한다면 코드는 금방 복잡해지고, 유지보수도 어려워집니다.

Django는 이런 문제를 해결하기 위해 Model과 Form 단계에 유효성 검사(validation)를 기본으로 내장해 두었습니다.

 

이 글에서는

  • Model에서 유효성 검사가 어떻게 정의되는지
  • Form과 View에서 그 검사가 어떻게 실행되는지
  • 유효하지 않을 때 Form을 왜 다시 만들지 않는지

실제 코드 기준으로 간단하고 직관적으로 살펴보겠습니다.

 

1. unique=True의 의미

title = models.CharField(
    max_length=50,
    unique=True,
    error_messages={'unique': '이미 있는 제목이네요!!!!'}
)
  • DB 레벨 + Django Model 레벨에서 동시에 적용되는 제약
  • 같은 title 값은 절대 중복 저장 불가

이미 존재하는 제목으로 저장 시도 → 유효성 검사 실패

 

이 검사는 Form에서 is_valid()를 호출할 때 자동으로 실행된다.

 

2. error_messages의 역할

error_messages={'unique': '이미 있는 제목이네요!!!!'}
  • 기본 에러 메시지를 개발자가 직접 커스터마이징
  • unique 제약에 걸렸을 때 이 문구가 그대로 사용자에게 전달됨

unique → “중복 데이터 방지” 및 error_messages → “사용자 친화적 에러 안내” 

이 모든 것이 Form 유효성 검사에 자동으로 연결됨

 

3. View 단계에서의 유효성 검사 흐름

1️⃣ is_valid()는 무엇을 하는가?

post_form = PostForm(request.POST)

if post_form.is_valid():
    new_post = post_form.save()

 

is_valid()를 호출하는 순간 Django는:

  • Model 필드 타입 검사
  • max_length 검사
  • null / blank 검사
  • unique 제약 검사
  • 에러 발생 시 errors에 저장

즉,

Model에서 정의한 모든 제약 조건이 여기서 한 번에 검증된다.

 

2️⃣ 왜 유효하지 않을 때 PostForm을 다시 만들지 않을까?

from django.shortcuts import render, redirect
from .models import Post
from .forms import PostForm

def post_create(request):
    if request.method == 'POST':
        # model_form은 Form과 Model을 함께 사용함.
        post_form = PostForm(request.POST)
        if post_form.is_valid():
            new_post = post_form.save()
            return redirect('post-detail', post_id=new_post.id) # urlname을 통한 redirect.


    post_form = PostForm()
    return render(request, 'posts/post_form.html', {'form': post_form})

새 Form을 만들어버리면 문제 발생

 

왜냐하면:

  • 사용자가 입력한 값이 모두 사라짐
  • 어떤 필드가 왜 틀렸는지 알 수 없음
  • 에러 메시지도 같이 날아감

3️⃣ 올바른 흐름 (현재 코드)

from django.shortcuts import render, redirect
from .models import Post
from .forms import PostForm

def post_create(request):
    if request.method == 'POST':
        # model_form은 Form과 Model을 함께 사용함.
        post_form = PostForm(request.POST)
        if post_form.is_valid():
            new_post = post_form.save()
            return redirect('post-detail', post_id=new_post.id) # urlname을 통한 redirect.

    else:
        post_form = PostForm()
    return render(request, 'posts/post_form.html', {'form': post_form})

이 방식의 장점:

  • 입력했던 값 그대로 유지
  • {{ form.errors }}로 에러 메시지 출력 가능

Django Form은

**“유효하지 않으면 스스로 에러 정보를 품고 있는 객체”**다.

 

즉 post_form을 새로 생성하면 저장된(form 입력 및 에러 내용) 데이터가 사라짐

 

4. 정리하면

  • Model: 규칙 정의 (unique, max_length, error_messages)
  • Form: 검증 수행 (is_valid)
  • View: 저장 여부 결정 (save or 재렌더링)

Django의 유효성 검사는
Model에서 정의하고 → Form에서 실행되며 → View에서 흐름을 제어한다.