Django에서 카테고리 필터 구현하기

Kangjik Kim·2025년 4월 29일
0

게시판이나 상품 목록과 같은 페이지에서 카테고리별 필터링은 매우 흔한 요구사항입니다.

오늘은 Django에서 간단하게 카테고리 필터를 구현하는 방법을 알아보겠습니다.

1. 모델 설정

먼저 카테고리를 가진 기본적인 모델을 정의합니다:

class Post(models.Model):
    CATEGORY_CHOICES = [
        ('TECH', '기술'),
        ('LIFE', '일상'),
        ('HOBBY', '취미'),
        ('OTHER', '기타'),
    ]

    title = models.CharField(max_length=200)
    content = models.TextField()
    category = models.CharField(
        max_length=20,
        choices=CATEGORY_CHOICES
    )
    created_at = models.DateTimeField(auto_now_add=True)

2. View 구현

카테고리 필터링을 처리할 View를 작성합니다:

from django.views.generic import TemplateView
from django.shortcuts import redirect

class PostListView(TemplateView):
    template_name = 'posts/list.html'

    def get(self, request, *args, **kwargs):
        # category 파라미터가 없으면 ALL로 리다이렉트
        if 'category' not in request.GET:
            return redirect(f"{request.path}?category=ALL")
        return super().get(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # 선택된 카테고리 가져오기
        selected_category = self.request.GET.get('category', 'ALL')

        # 게시글 필터링
        posts = Post.objects.all().order_by('-created_at')
        if selected_category != 'ALL':
            posts = posts.filter(category=selected_category)

        context.update({
            'posts': posts,
            'category_choices': Post.CATEGORY_CHOICES,
            'selected_category': selected_category,
        })
        return context

3. 템플릿 구현

카테고리 필터 UI를 구현합니다:

{% extends 'base.html' %}

{% block content %}
    {# 카테고리 필터 버튼 #}
    <div class="category-filter">
        <a href="?category=ALL"
           class="category-btn {% if selected_category == 'ALL' %}active{% endif %}">
            전체
        </a>
        {% for category_code, category_name in category_choices %}
            <a href="?category={{ category_code }}"
               class="category-btn {% if selected_category == category_code %}active{% endif %}">
                {{ category_name }}
            </a>
        {% endfor %}
    </div>

    {# 게시글 목록 #}
    <div class="post-list">
        {% for post in posts %}
            <div class="post-item">
                <h2>{{ post.title }}</h2>
                <p>카테고리: {{ post.get_category_display }}</p>
                <p>작성일: {{ post.created_at|date:"Y-m-d" }}</p>
            </div>
        {% endfor %}
    </div>
{% endblock %}

{% block extra_css %}
<style>
    .category-filter {
        margin: 20px 0;
    }
    .category-btn {
        display: inline-block;
        padding: 8px 16px;
        margin-right: 10px;
        border: 1px solid #ddd;
        border-radius: 4px;
        text-decoration: none;
        color: #333;
    }
    .category-btn.active {
        background-color: #007bff;
        color: white;
        border-color: #007bff;
    }
    .post-item {
        margin-bottom: 20px;
        padding: 15px;
        border: 1px solid #eee;
        border-radius: 4px;
    }
</style>
{% endblock %}

주요 기능

  1. 카테고리 없는 접속 처리:
    • 처음 페이지 접속 시 자동으로 ?category=ALL로 리다이렉트
  2. 카테고리 필터링:
    • 'ALL' 선택 시 모든 게시글 표시
    • 특정 카테고리 선택 시 해당 카테고리의 게시글만 표시
  3. UI/UX:
    • 현재 선택된 카테고리 버튼 강조 표시
    • 깔끔한 버튼 스타일링

확장 가능성

  1. 페이지네이션 추가:
    • 카테고리 필터와 함께 페이지네이션 구현 가능
  2. 다중 필터:
    • 날짜, 태그 등 추가 필터 조건 구현 가능
  3. 정렬 기능:
    • 최신순, 조회순 등 정렬 옵션 추가 가능

이렇게 간단하게 Django에서 카테고리 필터를 구현할 수 있습니다.

0개의 댓글