함수뷰 클래스뷰 제너릭뷰

HY_1023·2026년 3월 17일

헷갈리는 부분 정리

목록 보기
24/40

함수형 View (FBV, Function-Based View)

Django에서 뷰를 함수로 작성하는 방식이에요.

# views.py
from django.shortcuts import render

def study_list(request):
    studies = Study.objects.all()
    return render(request, 'study/list.html', {'studies': studies})

CBV (Class-Based View) 와 비교

# ❌ FBV
def study_list(request):
    studies = Study.objects.all()
    return render(request, 'study/list.html', {'studies': studies})

# ✅ CBV
class StudyListView(ListView):
    model = Study
    template_name = 'study/list.html'
FBVCBV
구조함수클래스
난이도쉬움어려움
코드량많음적음
유연성높음낮음

Django 뷰의 종류: 함수뷰 vs 클래스뷰 vs 제너릭뷰

1. 함수 기반 뷰 (Function-Based View, FBV)

from django.shortcuts import render, get_object_or_404

def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, 'blog/post_detail.html', {'post': post})

특징

  • 가장 단순하고 직관적
  • 흐름이 명확해서 읽기 쉬움
  • HTTP 메서드 분기를 직접 처리해야 함 (if request.method == 'POST':)
  • 재사용성이 낮음

2. 클래스 기반 뷰 (Class-Based View, CBV)

from django.views import View

class PostDetailView(View):
    def get(self, request, pk):
        post = get_object_or_404(Post, pk=pk)
        return render(request, 'blog/post_detail.html', {'post': post})

    def post(self, request, pk):
        # POST 요청 처리
        ...

특징

  • HTTP 메서드(GET, POST 등)를 메서드로 자동 분기
  • 상속과 믹스인(Mixin)으로 코드 재사용 가능
  • 복잡한 뷰일수록 구조화하기 유리
  • FBV보다 초기 학습 곡선이 있음

3. 제너릭 뷰 (Generic View)

CBV를 더 추상화한 것으로, Django가 CRUD 패턴을 미리 구현해 놓은 뷰

from django.views.generic import ListView, DetailView, CreateView

class PostListView(ListView):
    model = Post
    template_name = 'blog/post_list.html'
    context_object_name = 'posts'

class PostDetailView(DetailView):
    model = Post

class PostCreateView(CreateView):
    model = Post
    fields = ['title', 'content']
    success_url = '/posts/'

주요 종류

클래스용도
ListView목록 조회
DetailView단일 객체 조회
CreateView객체 생성
UpdateView객체 수정
DeleteView객체 삭제
TemplateView단순 템플릿 렌더링

비교 요약

구분함수뷰 (FBV)클래스뷰 (CBV)제너릭뷰
구조함수클래스클래스 (CBV 확장)
코드량많음중간매우 적음
가독성직관적구조적선언적
재사용성낮음높음매우 높음
유연성매우 높음높음낮음 (커스터마이징 필요)
적합한 경우단순/특수 로직복잡한 로직표준 CRUD

언제 무엇을 쓸까?

  • FBV → 로직이 복잡하거나 특수한 경우, 팀원 모두 Django에 익숙하지 않을 때
  • CBV → 여러 뷰에서 공통 로직을 공유해야 할 때 (믹스인 활용)
  • 제너릭뷰 → 단순한 CRUD 페이지, 빠른 개발이 필요할 때

실무에서는 세 가지를 상황에 맞게 혼용하는 것이 일반적입니다.


FBV vs CBV vs 제너릭뷰 — CRUD 흐름 비교


CREATE (생성)

FBV

def post_create(request):
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('post_list')
    else:
        form = PostForm()
    return render(request, 'post_form.html', {'form': form})

CBV

class PostCreateView(View):
    def get(self, request):
        form = PostForm()
        return render(request, 'post_form.html', {'form': form})

    def post(self, request):
        form = PostForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('post_list')
        return render(request, 'post_form.html', {'form': form})

제너릭뷰

class PostCreateView(CreateView):
    model = Post
    fields = ['title', 'content']
    success_url = '/posts/'
    # GET/POST 처리, form 생성, 유효성 검사, 저장, 리다이렉트 → 모두 자동

READ (조회)

FBV

# 목록
def post_list(request):
    posts = Post.objects.all()
    return render(request, 'post_list.html', {'posts': posts})

# 상세
def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, 'post_detail.html', {'post': post})

CBV

class PostListView(View):
    def get(self, request):
        posts = Post.objects.all()
        return render(request, 'post_list.html', {'posts': posts})

class PostDetailView(View):
    def get(self, request, pk):
        post = get_object_or_404(Post, pk=pk)
        return render(request, 'post_detail.html', {'post': post})

제너릭뷰

class PostListView(ListView):
    model = Post
    # Post.objects.all() 자동 실행, 'post_list.html' 자동 탐색

class PostDetailView(DetailView):
    model = Post
    # pk로 객체 자동 조회, 없으면 404 자동 처리

UPDATE (수정)

FBV

def post_update(request, pk):
    post = get_object_or_404(Post, pk=pk)
    if request.method == 'POST':
        form = PostForm(request.POST, instance=post)  # ← instance 직접 넘겨야 함
        if form.is_valid():
            form.save()
            return redirect('post_detail', pk=pk)
    else:
        form = PostForm(instance=post)
    return render(request, 'post_form.html', {'form': form})

CBV

class PostUpdateView(View):
    def get(self, request, pk):
        post = get_object_or_404(Post, pk=pk)
        form = PostForm(instance=post)
        return render(request, 'post_form.html', {'form': form})

    def post(self, request, pk):
        post = get_object_or_404(Post, pk=pk)
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            form.save()
            return redirect('post_detail', pk=pk)
        return render(request, 'post_form.html', {'form': form})

제너릭뷰

class PostUpdateView(UpdateView):
    model = Post
    fields = ['title', 'content']
    success_url = '/posts/'
    # 기존 데이터 자동 바인딩, 유효성 검사, 저장 모두 자동

DELETE (삭제)

FBV

def post_delete(request, pk):
    post = get_object_or_404(Post, pk=pk)
    if request.method == 'POST':
        post.delete()
        return redirect('post_list')
    return render(request, 'post_confirm_delete.html', {'post': post})

CBV

class PostDeleteView(View):
    def get(self, request, pk):
        post = get_object_or_404(Post, pk=pk)
        return render(request, 'post_confirm_delete.html', {'post': post})

    def post(self, request, pk):
        post = get_object_or_404(Post, pk=pk)
        post.delete()
        return redirect('post_list')

제너릭뷰

class PostDeleteView(DeleteView):
    model = Post
    success_url = '/posts/'
    # 확인 페이지 렌더링 → POST 수신 → 삭제 → 리다이렉트 자동

흐름 구조 비교 요약

FBV
요청 → if method == 'POST' 분기 → 직접 폼/쿼리 처리 → 응답

CBV
요청 → dispatch() → get() / post() 자동 분기 → 처리 → 응답

제너릭뷰
요청 → dispatch() → get_object() / get_form() 자동 실행
     → form_valid() / form_invalid() 자동 분기 → 응답

핵심 차이 한 줄 정리

핵심
FBV모든 흐름을 내가 직접 작성
CBVHTTP 메서드 분기를 Django가 처리, 나머지는 직접
제너릭뷰CRUD 흐름 전체를 Django가 처리, 나는 설정만
profile
개발언어를 배우는 과정 기록

0개의 댓글