Developer's Development
3.4.9 [Django] Class-based View(CBV) 본문
CBV 개요
Django에서 클래스를 기반으로 View를 구성하는 방식이다.
- 기존의 함수형 뷰(Function-based view, FBV)는 단순하고 명확하지만, 복잡한 뷰 로직이 늘어나면 코드가 길어지고 유지보수가 어렵다.
- CBV는 상속과 메소드 오버라이딩을 통해 공통 기능을 재사용하고, 가독성과 확장성을 확보할 수 있다.
- CBV의 기본 구조
ex) TemplateView
TemplateView는 단순히 템플릿만 렌더링할 때 사용하는 CBV이다.
- 브라우저 요청 → 해당 클래스 인스턴스 생성 → 내부 get() 메서드 실행 → 템플릿 렌더링
Generic CBV 종류
| CBV | 역할 |
| ListView | 객체 목록 조회 |
| DetailView | 단일 객체 상세 조회 |
| CreateView | 객체 생성 폼 |
| UpdateView | 객체 수정 폼 |
| DeleteView | 객체 삭제 |
👉🏻 모델 예시
# models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
published_date = models.DateField()
- ListView
- model: 조회 대상 모델
- template_name: 렌더링할 템플릿 파일
- context_object_name: 템플릿에서 사용할 객체 이름
from django.views.generic import ListView
from .models import Book
class BookListView(ListView):
model = Book
template_name = 'book_list.html'
context_object_name = 'books'
- DetailView
URL에 <int:pk>가 필요하다.
- path('books/<int:pk>/', BookDetailView.as_view())
from django.views.generic import DetailView
class BookDetailView(DetailView):
model = Book
template_name = 'book_detail.html'
context_object_name = 'book'
- CreateView
- success_url: 폼 제출 후 리다이렉션 할 경로
from django.views.generic.edit import CreateView
from .models import Book
class BookCreateView(CreateView):
model = Book
fields = ['title', 'author', 'published_date']
template_name = 'book_form.html'
success_url = '/books/'
- UpdateView
기존 데이터를 폼에 채워주고 수정 가능하다.
from django.views.generic.edit import UpdateView
class BookUpdateView(UpdateView):
model = Book
fields = ['title', 'author', 'published_date']
template_name = 'book_form.html'
success_url = '/books/'
- DeleteView
from django.views.generic.edit import DeleteView
class BookDeleteView(DeleteView):
model = Book
template_name = 'book_confirm_delete.html'
success_url = '/books/'
CBV 오버라이딩 및 Method Flow
CBV 동작 방식
- CBV는 내부적으로 dispatch() 메서드를 통해 요청 메서드(GET, POST 등)를 구분한다.
👉🏻 메서드 오버라이딩 예
- form_valid(): 폼이 유효할 때 실행되는 메서드
- 필요한 곳에서 메서드만 오버라이딩하면 동작 제어 가능
class BookCreateView(CreateView):
...
def form_valid(self, form):
print("폼 유효성 검사 통과!")
return super().form_valid(form)
MRO와 super()
다중 상속 기반
- CBV 내부 구조는 다중 상속으로 구성되므로 MRO(Method Resolution Order)를 이해해야 한다.
- super 함수는 MRO에 따라 부모 클래스 메서드를 호출
print(BookCreateView.__mro__)
실습
_04_django_form 프로젝트에서 그대로 진행
👉🏻 main/urls.py 추가
from .views import BookListView, BookDetailView, BookCreateView
urlpatterns = [
...,
path('books/', BookListView.as_view(), name='book_list'),
path('books/<int:pk>', BookDetailView.as_view(), name='book_detail'),
path('books/create', BookCreateView.as_view(), name='book_create'),
# books/<int:pk>/update - url path 추가
# books/<int:pk>/delete - url path 추가
]
👉🏻 main/views.py 수정
from .models import Book
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
class BookListView(ListView):
model = Book
template_name = 'book_list.html'
context_object_name = 'books'
class BookDetailView(DetailView):
model = Book
template_name = 'book_detail.html'
class BookCreateView(CreateView):
model = Book
form_class = BookForm
template_name = 'book_form.html'
success_url = reverse_lazy('main:book_list')
# BookUpdateView 작성
# BookDeleteView 작성
👉🏻 main/templates에 템플릿 HTML 추가 및 수정
book_form.html (수정)
...
<h1>도서 등록</h1> <!-- [수정]이면 "도서 수정"으로 변경 -->
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">저장</button>
</form>
book_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>도서 목록</title>
</head>
<body>
<h1>도서 목록</h1>
<ul>
{% for book in books %}
<li><a href="{% url 'main:book_detail' book.pk %}">{{ book.title }}</a></li>
{% empty %}
<li>등록된 도서가 없습니다.</li>
{% endfor %}
</ul>
<hr>
<a href="{% url 'main:book_create' %}">새 도서 등록</a>
</body>
</html>
book_detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ object.title }}</title>
</head>
<body>
{# <p>{{ book }}</p> #}
<h1>{{ object.title }}</h1>
<p>저자: {{ object.author }}</p>
<p>출판일: {{ object.published_date }}</p>
<p>가격: {{ object.price }}</p>
<a href="{% url 'main:book_list' %}">목록</a>
<!-- 수정/삭제 추가 -->
<!-- [수정] > book_form.html로 이동 (기존 book 정보 현출) > 수정사항 변경 후 [저장] > book_list.html 현출 -->
<!-- [삭제] > book_confirm_delete.html로 이동 -->
</body>
</html>
book_confirm_delete.html
<h1>정말로 삭제하시겠습니까?😥</h1>
<p>대상 도서: {{ }}</p>
<!-- 삭제/취소 버튼 -->
<!-- [삭제] > 삭제 후 book_list.html 현출
[취소] > 삭제하지 않고 book_detail.html로 복귀 -->'AI 활용 애플리케이션 개발 > Django Framework' 카테고리의 다른 글
| 3.4.10 [Django] Fast API (RESTful API) (0) | 2025.10.28 |
|---|---|
| 3.4.8 [Django] Form 처리 (0) | 2025.10.19 |
| 3.4.7 [Django] Model-DB 연동 (0) | 2025.10.19 |
| 3.4.6 [Django] View-Template 연동 (0) | 2025.10.16 |