[장고] ListView 완벽 가이드 (예제: 블로그 글 리스트로 나열하기)

소요 시간: 5분

Django의 클래스 기반 뷰(Class-Based View)는 웹 애플리케이션 개발을 모듈화하고 재사용성을 높이는 데 유용합니다. 그 중에서도 ListView는 특정 모델의 객체 목록을 표시하는 데 자주 사용됩니다. 이 글에서는 블로그 포스트 모델을 예제로 하여 ListView를 설정하고 커스터마이징하는 방법을 자세히 설명합니다.


ListView 기본 설정하기

ListView는 모델의 객체 목록을 쉽게 렌더링할 수 있는 뷰입니다. 기본 설정부터 차근차근 알아보겠습니다.

1. 뷰 클래스 정의

ListView를 정의하고 설정하는 방법을 설명합니다.

# views.py
from django.views.generic import ListView
from .models import Post

class PostListView(ListView):
    model = Post
    template_name = 'blog/post_list.html'
    context_object_name = 'posts'
    paginate_by = 10  # 페이지네이션 설정

위 코드에서는 Post 모델의 객체 리스트를 보여주는 뷰를 정의했습니다. 템플릿 파일은 'blog/post_list.html'이며, 템플릿에서 객체 리스트는 'posts'라는 이름으로 접근할 수 있습니다. 또한 한 페이지에 10개의 객체를 표시하도록 설정했습니다.

2. URL 설정

뷰를 URL에 매핑하여 사용자가 접근할 수 있도록 합니다.

# urls.py
from django.urls import path
from .views import PostListView

urlpatterns = [
    path('posts/', PostListView.as_view(), name='post-list'),
]

위 코드는 PostListView'posts/' 경로에 매핑하고, 이 URL 패턴을 'post-list'라는 이름으로 설정합니다.

3. 템플릿 설정

객체 리스트를 렌더링할 템플릿을 정의합니다.

<!-- templates/blog/post_list.html -->
{% extends "base.html" %}

{% block content %}
  <h2>Blog Posts</h2>
  <ul>
    {% for post in posts %}
      <li>{{ post.title }}</li>  <!-- Post 모델의 필드에 맞게 조정 -->
    {% endfor %}
  </ul>

  <!-- 페이지네이션 -->
  <div class="pagination">
    <span class="step-links">
        {% if posts.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ posts.previous_page_number }}">previous</a>
        {% endif %}

        <span class="current">
            Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
        </span>

        {% if posts.has_next %}
            <a href="?page={{ posts.next_page_number }}">next</a>
            <a href="?page={{ posts.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
  </div>
{% endblock %}

위 템플릿에서는 Post 객체의 리스트를 렌더링합니다. 각 객체의 제목을 리스트 항목으로 표시하고, 페이지네이션 링크를 추가하여 페이지를 이동할 수 있도록 합니다.


ListView 커스터마이징

기본 설정 외에도 다양한 방법으로 ListView를 커스터마이징할 수 있습니다.

쿼리셋 커스터마이징

기본 쿼리셋을 변경하는 방법을 소개합니다.

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

    def get_queryset(self):
        # 필터링된 쿼리셋을 반환
        return Post.objects.filter(published=True)

위 코드에서는 published 필드가 True인 객체만을 반환하도록 쿼리셋을 커스터마이징했습니다.

추가 컨텍스트 데이터 전달

뷰에서 추가적인 컨텍스트 데이터를 템플릿에 전달하는 방법을 설명합니다.

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

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['extra_data'] = '추가적인 데이터'
        return context

위 코드에서는 get_context_data 메서드를 오버라이드하여 템플릿에 'extra_data'라는 추가적인 컨텍스트 데이터를 전달합니다.

필터 및 검색 기능 추가

사용자 입력에 따라 쿼리셋을 필터링하는 방법을 소개합니다.

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

    def get_queryset(self):
        queryset = super().get_queryset()
        search_query = self.request.GET.get('q', '')
        if search_query:
            queryset = queryset.filter(title__icontains=search_query)
        return queryset

위 코드에서는 GET 요청에서 'q' 파라미터를 가져와 title 필드에 해당 문자열이 포함된 객체만 필터링하여 검색 기능을 구현했습니다.


결론

Django의 ListView는 객체 목록을 쉽게 렌더링할 수 있는 강력한 도구입니다. 기본 설정부터 커스터마이징까지 다양한 방법으로 활용할 수 있습니다. 이 글에서는 블로그 포스트 모델을 예제로 하여 ListView의 기본 설정 방법과 쿼리셋 커스터마이징, 추가 컨텍스트 데이터 전달, 필터 및 검색 기능 추가 방법을 설명했습니다. 이를 바탕으로 다양한 요구사항에 맞는 뷰를 구현할 수 있을 것입니다.

장고 리스트