이번 포스트는 Django 클래스 기반 뷰(CBV) 시리즈 5편으로, CreateView, UpdateView, DeleteView를 활용하여 CRUD를 손쉽게 구현하는 방법을 다룹니다. 지난 글에서 다룬 ListView, DetailView와 함께 조합하면, 데이터 조회 뿐만 아니라 생성(Create), 수정(Update), 삭제(Delete) 가 가능한 완전한 CRUD 애플리케이션을 빠르게 구성할 수 있습니다.
지난 글 ListView, DetailView 를 아직 읽지않으신 분들은 이전 글을 먼저 읽어보시길 권장합니다.
클래스 기반 뷰(CBV) 탐구 시리즈 ④ - ListView & DetailView 활용법
“Django 제네릭 뷰로 손쉽게 CRUD를 완성하고, 생산성을 극대화하세요!”
앞선 포스트들에서는 CBV의 기본 구조와 ListView, DetailView를 통한 읽기(READ) 작업에 집중해 왔습니다.
이번 글에서는 Django가 제공하는 편리한 CreateView, UpdateView, DeleteView를 살펴봄으로써, 작성(Create), 수정(Update), 삭제(Delete) 기능까지 체계적으로 갖춘 웹 애플리케이션을 완성해 보겠습니다.
1. CreateView – 데이터 생성하기
1.1 기본 개념과 구조
CreateView는 Django 제네릭 뷰 중 “새로운 객체를 생성”하는 데 특화된 클래스입니다.
-
폼 처리를 자동화:
FormView
기능을 내부적으로 활용해,form_valid()
내에서 새 객체를 저장하고 성공 시 URL로 리디렉션합니다. -
ModelForm과 궁합이 좋음:
model
속성과fields
, 또는form_class
를 지정하면, 자동으로 폼이 생성되고 처리됩니다.
# views.py
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .models import Post
class PostCreateView(CreateView):
model = Post
fields = ['title', 'content'] # 또는 form_class = PostForm
template_name = 'post_form.html'
success_url = reverse_lazy('post_list') # 작성 성공 시 이동할 URL
1.2 urls.py 연결 예시
# urls.py
from django.urls import path
from .views import PostCreateView
urlpatterns = [
path('posts/create/', PostCreateView.as_view(), name='post_create'),
]
1.3 템플릿 예시: post_form.html
<!DOCTYPE html>
<html>
<head>
<title>새 글 작성</title>
</head>
<body>
<h1>새 게시글 작성</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">저장하기</button>
</form>
</body>
</html>
Tip:
fields
대신form_class
를 사용하면,forms.py
에서ModelForm
을 정의해 더욱 정교하게 폼을 제어할 수 있습니다.
2. UpdateView – 데이터 수정하기
2.1 기본 개념과 구조
UpdateView는 기존 객체를 찾아 수정하는 데 특화된 제네릭 뷰입니다.
-
URL에 pk 또는 slug 값을 사용해 해당 객체를 자동으로 조회합니다.
-
폼에 기존 데이터가 자동으로 채워진 상태에서 렌더링되며, 사용자가 수정 후 제출하면 DB에 변경사항을 저장합니다.
# views.py
from django.views.generic.edit import UpdateView
from django.urls import reverse_lazy
from .models import Post
class PostUpdateView(UpdateView):
model = Post
fields = ['title', 'content']
template_name = 'post_form.html'
success_url = reverse_lazy('post_list') # 수정 성공 시 이동할 URL
2.2 urls.py 연결 예시
# urls.py
from .views import PostUpdateView
urlpatterns = [
path('posts/<int:pk>/edit/', PostUpdateView.as_view(), name='post_update'),
]
2.3 템플릿 예시 (재활용 가능)
CreateView와 비슷하게 post_form.html 템플릿을 재사용할 수도 있습니다.
UpdateView에서는 form.instance
가 이미 DB에 저장된 객체이므로, 기존 데이터가 폼에 자동 입력됩니다.
3. DeleteView – 데이터 삭제하기
3.1 기본 개념과 구조
DeleteView는 특정 객체를 찾아 삭제하는 데 쓰이는 제네릭 뷰입니다.
-
사용자가 삭제 확인 폼을 제출하면, 해당 객체가 DB에서 제거되고 지정된 URL로 리디렉션됩니다.
-
보안상 “삭제 확인”을 거치는 템플릿을 하나 만들어 두는 것을 권장합니다.
# views.py
from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from .models import Post
class PostDeleteView(DeleteView):
model = Post
template_name = 'post_confirm_delete.html'
success_url = reverse_lazy('post_list')
3.2 urls.py 연결 예시
# urls.py
from .views import PostDeleteView
urlpatterns = [
path('posts/<int:pk>/delete/', PostDeleteView.as_view(), name='post_delete'),
]
3.3 템플릿 예시: post_confirm_delete.html
<!DOCTYPE html>
<html>
<head>
<title>게시글 삭제</title>
</head>
<body>
<h1>게시글 삭제</h1>
<p>정말 이 글을 삭제하시겠습니까?</p>
<form method="post">
{% csrf_token %}
<button type="submit">삭제</button>
<a href="{% url 'post_list' %}">취소</a>
</form>
</body>
</html>
주의: DeleteView는 사용자 실수로 인한 삭제를 방지하기 위해 “삭제 확인” 과정을 거치도록 설계됩니다.
바로 삭제를 원한다면, 다른 방식(예: FormView나 직접 로직 작성)으로 구현해야 합니다.
4. CRUD를 완성하는 흐름 한눈에 보기
4.1 예시 모델: Post
# models.py
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
4.2 urlpatterns (간략 버전)
urlpatterns = [
# 1) READ
path('posts/', PostListView.as_view(), name='post_list'), # 목록(ListView)
path('posts/<int:pk>/', PostDetailView.as_view(), name='post_detail'), # 상세(DetailView)
# 2) CREATE
path('posts/create/', PostCreateView.as_view(), name='post_create'),
# 3) UPDATE
path('posts/<int:pk>/edit/', PostUpdateView.as_view(), name='post_update'),
# 4) DELETE
path('posts/<int:pk>/delete/', PostDeleteView.as_view(), name='post_delete'),
]
4.3 권장 폴더 구조와 템플릿 파일
-
templates/
-
post_list.html
-
post_detail.html
-
post_form.html
(CreateView, UpdateView 공용) -
post_confirm_delete.html
(DeleteView)
-
5. Create/Update/DeleteView를 커스터마이징하는 방법
5.1 form_class로 세분화된 폼 제어
class PostCreateView(CreateView):
model = Post
form_class = PostForm # ModelForm을 지정
...
PostForm
에서 필드 검증 또는 위젯 지정을 세부적으로 설정할 수 있어 더 유연한 폼 처리가 가능합니다.
5.2 get_success_url()로 동적 리디렉션
def get_success_url(self):
# 예: 새로 생성된 Post의 pk를 이용해 상세 페이지로 이동
return reverse_lazy('post_detail', kwargs={'pk': self.object.pk})
self.object
는 현재 Create/Update에서 처리된 모델 인스턴스를 가리킵니다.
5.3 접근 권한 제어, Mixin 추가
-
LoginRequiredMixin 등과 조합하여 “로그인 유저만 작성/수정/삭제 가능”하게 만들 수 있습니다.
-
Permission을 세부적으로 관리하고 싶다면 PermissionRequiredMixin 또는 UserPassesTestMixin도 고려해 보세요.
6. FBV와 비교해 보기
기능 | FBV (함수 기반 뷰) | Create/Update/DeleteView (클래스 기반 뷰) |
---|---|---|
작성(Create) | request.method == 'POST' 조건문, ModelForm 직접 정의, 저장 로직 직접 작성 |
CreateView: 상속만 하면 폼 생성→저장→리디렉트가 자동 처리 |
수정(Update) | 기존 객체를 fetch 후 폼에 넣고, POST 처리 시 다시 검증·저장 로직 반복 | UpdateView: 기존 객체 불러옴→수정→저장, 로직 자동화 |
삭제(Delete) | GET→삭제 확인 페이지 렌더링, POST→삭제 처리, 리디렉트 등 모든 로직 함수 안에 혼재 | DeleteView: 삭제 대상 객체 가져오기, 삭제 후 이동 처리 모두 내장 로직 제공 |
가독성 / 유지보수 | 로직 분기가 많아 코드 길어지기 쉬움, 여러 장소에서 동일 로직 중복 | 메서드 오버라이딩으로 필요한 부분만 재정의, 중복 최소화 가능 |
개발 생산성(핵심 키워드) | “수작업 많음, 시간 소모, 코드 중복” | “개발 속도 향상(Time-saving)과 유지 보수성 개선(Productivity boost)” |
7. 마무리: 제네릭 뷰를 통해 CRUD를 빠르고 깔끔하게 구현하자!
CreateView, UpdateView, DeleteView를 이용하면, Django에서 CRUD 작업을 극도로 간결하고 직관적인 코드로 완성할 수 있습니다.
특히, 중복되는 폼 처리 로직이나, 데이터 저장 후 리디렉션 등의 패턴이 자동으로 처리되므로 개발자가 집중해야 할 부분은 “비즈니스 로직”과 “UI/UX”가 됩니다.
이제
ListView
+DetailView
+CreateView
+UpdateView
+DeleteView
를 모두 이해했다면, Django에서 기본적인 CRUD 애플리케이션을 손쉽게 구성할 수 있습니다!
다음 글에서는 TemplateView & RedirectView를 다루어 간단한 페이지 렌더링과 리디렉션 처리까지 매끄럽게 자동화하는 방법을 살펴볼 예정입니다.
이전 글 다시 보기
“Django의 제네릭 뷰를 활용해 CRUD 구현을 자동화하고,
프로젝트 개발 속도와 코드 품질을 동시에 끌어올리세요!”
댓글이 없습니다.