Chapter 5-2 📌 Django CBV - ListView로 블로그 목록 + 검색 + 페이지네이션 구현하기

2025. 5. 8. 10:01·Django

📌 Django CBV - ListView로 블로그 목록 + 검색 + 페이지네이션 구현하기


1️⃣ FBV와 분리된 CBV 구조 설계

기존의 views.py 와는 구분하기 위해 cb_views.py 를 새로 만들어 CBV 관련 로직을 작성합니다.

# blog/cb_views.py
from django.db.models import Q
from django.views.generic import ListView
from blog.models import Blog

class BlogListView(ListView):
    queryset = Blog.objects.all()
    template_name = 'blog_list.html'
    paginate_by = 10
    ordering = ('-created_at', )

    def get_queryset(self):
        queryset = super().get_queryset()
        q = self.request.GET.get('q')
        if q:
            queryset = queryset.filter(
                Q(title__icontains=q) |
                Q(content__icontains=q)
            )
        return queryset

2️⃣ CBV URL 연결하기

# config/urls.py
from blog import cb_views

urlpatterns = [
    path('cb/', cb_views.BlogListView.as_view(), name='cb_blog_list'),
]

✔️ as_view() 메서드를 호출하여 클래스 기반 뷰 인스턴스를 생성합니다.


3️⃣ 템플릿에서 object_list 활용하기

CBV에서 queryset이 렌더링될 때 기본적으로 object_list라는 이름으로 템플릿에 전달됩니다.

{# blog/blog_list.html #}
{% extends 'base.html' %}
{% block content %}
    <h1>블로그 목록</h1>
    <p style="text-align: right">
        <a href="{% url 'blog_create' %}">생성</a>
    </p>

    {% for blog in object_list %}
        <p>
            <a href="{% url 'blog_detail' blog.pk %}">
                ({{ blog.id }}){{ blog.title }} - <small>{{ blog.created_at|date:"Y-m-d" }}</small>
            </a>
        </p>
    {% endfor %}

    <form method="get" style="margin-bottom: 10px;">
        <input name="q" type="text" placeholder="검색어를 입력하세요." value="{{ request.GET.q }}">
        <button>검색</button>
    </form>

4️⃣ 기존 FBV에서도 동일한 변수명 적용

FBV에서도 object_list와 page_obj를 전달하도록 수정합니다.

# blog/views.py
def blog_list(request):
    ...
    context = {
        'object_list': page_object.object_list,
        'page_obj': page_object,
    }
    return render(request, 'blog_list.html', context)

5️⃣ 페이지네이션 기능 추가 (CBV + FBV 공용)

{# blog_list.html 페이지네이션 영역 #}
<div>
    {% if page_obj.has_previous %}
        <a href="?page=1{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">&laquo 첫번째</a>
        <a href="?page={{ page_obj.previous_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">이전</a>
    {% endif %}

    {% if page_obj.number|add:2 > 1 %}
        <a href="?page={{ page_obj.number|add:-3 }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">&hellip;</a>
    {% endif %}

    {% for i in page_obj.paginator.page_range %}
        {% if page_obj.number == i %}
            <span>(현재페이지)</span>
        {% elif i > page_obj.number|add:-3 and i < page_obj.number|add:3 %}
            <a href="?page={{ i }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">{{ i }}</a>
        {% endif %}
    {% endfor %}

    {% if page_obj.paginator.num_pages > page_obj.number|add:2 %}
        <a href="?page={{ page_obj.number|add:3 }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">&hellip;</a>
    {% endif %}

    {% if page_obj.has_next %}
        <a href="?page={{ page_obj.next_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">다음</a>
        <a href="?page={{ page_obj.paginator.num_pages }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">마지막 &raquo</a>
    {% endif %}
</div>
{% endblock %}

✅ 정리

  • CBV는 ListView 상속을 통해 더 간결하고 구조화된 코드 작성이 가능합니다.
  • object_list, page_obj 등 변수명을 통일하면 FBV와 CBV가 같은 템플릿을 공유할 수 있습니다.
  • 검색 기능과 페이지네이션도 CBV에서 유연하게 구현할 수 있습니다.

💡 제너릭 뷰는 기본 동작이 많아 생산성이 매우 높습니다. 꼭 활용해보세요!

'Django' 카테고리의 다른 글

Chapter 5-4 📌 Django CBV - LoginRequiredMixin과 CreateView로 블로그 글 작성 기능 구현하기  (0) 2025.05.08
Chapter 5-3 📌 Django CBV - DetailView로 블로그 상세 페이지 구현 및 커스터마이징  (0) 2025.05.08
Chapter 5-1 📌 Django Class-Based Views (CBV) 완전 정복 가이드  (0) 2025.05.08
Chapter 4-6 Django 블로그 검색 기능 구현하기  (0) 2025.05.07
Chapter 4-7 Django 블로그 삭제 기능 만들기  (0) 2025.05.07
'Django' 카테고리의 다른 글
  • Chapter 5-4 📌 Django CBV - LoginRequiredMixin과 CreateView로 블로그 글 작성 기능 구현하기
  • Chapter 5-3 📌 Django CBV - DetailView로 블로그 상세 페이지 구현 및 커스터마이징
  • Chapter 5-1 📌 Django Class-Based Views (CBV) 완전 정복 가이드
  • Chapter 4-6 Django 블로그 검색 기능 구현하기
Chansman
Chansman
안녕하세요! 코딩을 시작한 지 얼마 되지 않은 초보 개발자 찬스맨입니다. 이 블로그는 제 학습 기록을 남기고, 다양한 코딩 실습을 통해 성장하는 과정을 공유하려고 합니다. 초보자의 눈높이에 맞춘 실습과 팁, 그리고 개발하면서 겪은 어려움과 해결 과정을 솔직하게 풀어내려 합니다. 함께 성장하는 개발자 커뮤니티가 되기를 바랍니다.
  • Chansman
    찬스맨의 프로그래밍 스토리
    Chansman
  • 전체
    오늘
    어제
    • 분류 전체보기 (787)
      • Python (32)
      • 프로젝트 (110)
      • 과제 (25)
      • Database (40)
      • 멘토링 (11)
      • 특강 (37)
      • 기술블로그 (41)
      • 기술블로그-Fastapi편 (33)
      • 기술블로그-Django편 (153)
      • 기술블로그-Flask편 (36)
      • AI 분석 (5)
      • HTML & CSS (31)
      • JavaScript (17)
      • AWS_Cloud (21)
      • 웹스크래핑과 데이터 수집 (14)
      • Flask (42)
      • Django (77)
      • Fastapi (16)
      • 연예 (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    youngprofessionals
    btsdischarge
    btscomeback
    btsreunion
    smartphonedurability
    lawsuitculture
    livebroadcast
    bts
    btsjungkook
    chatgpterror
    titaniumcase
    chinanightlife
    homebartrend
    remittance
    RM
    urbantrends
    americaparty
    trumpmuskclash
    college reunions
    travel ban
    classaction
    americanlaw
    뷔
    self-growth
    gpterror
    newpoliticalparty
    basalcellcarcinoma
    hotcoffeecase
    global politics
    life reflection
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Chansman
Chapter 5-2 📌 Django CBV - ListView로 블로그 목록 + 검색 + 페이지네이션 구현하기
상단으로

티스토리툴바