[장고] DetailView에 이전 및 다음 글 링크 추가하기

소요 시간: 5분

Django를 활용하여 블로그를 개발할 때, 각 글의 상세 페이지에 이전 글과 다음 글로 이동할 수 있는 링크를 제공하면 사용자 경험을 크게 향상시킬 수 있습니다. 이번 포스트에서는 Django의 DetailView를 활용하여 블로그 글의 상세 정보를 보여주는 방법과, 이전 글 및 다음 글 링크를 컨텍스트 변수에 추가하는 방법을 상세히 설명하겠습니다.


모델 정의

우선, 블로그 포스트 모델을 정의합니다. 이 모델은 글의 제목, 내용, 생성 일자를 기록합니다.

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title


DetailView 설정

이제 Django의 DetailView를 확장하여 사용합니다. get_context_data 메서드를 오버라이드하여 컨텍스트에 이전 글과 다음 글을 추가합니다.

from django.views.generic.detail import DetailView
from django.shortcuts import get_object_or_404
from .models import Post

class PostDetailView(DetailView):
    model = Post
    template_name = 'post_detail.html'
    context_object_name = 'post'

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

        # 이전 글
        previous_post = Post.objects.filter(created_at__lt=post.created_at).order_by('-created_at').first()
        # 다음 글
        next_post = Post.objects.filter(created_at__gt=post.created_at).order_by('created_at').first()

        context['previous_post'] = previous_post
        context['next_post'] = next_post

        return context

여기서 get_context_data 메서드는 현재 글의 생성 날짜를 기준으로 이전 글과 다음 글을 조회하여 컨텍스트에 추가합니다. previous_post는 현재 글보다 이전에 생성된 글 중 가장 최근의 글을, next_post는 현재 글보다 이후에 생성된 글 중 가장 오래된 글을 가져옵니다.


템플릿 작성

이제 템플릿에서 이전 글과 다음 글 링크를 표시합니다. 컨텍스트에 추가된 previous_post와 next_post 변수를 사용하여 각 링크를 설정합니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ post.title }}</title>
    <link rel="stylesheet" href="{% static 'styles.css' %}">
</head>
<body>
    <div class="content">
        <h1>{{ post.title }}</h1>
        <div>{{ post.content }}</div>
    </div>

    <div class="post-navigation">
        {% if previous_post %}
            <a href="{% url 'post_detail' previous_post.pk %}" class="prev-post">Previous Post: {{ previous_post.title }}</a>
        {% endif %}
        {% if next_post %}
            <a href="{% url 'post_detail' next_post.pk %}" class="next-post">Next Post: {{ next_post.title }}</a>
        {% endif %}
    </div>
</body>
</html>

템플릿에서는 previous_post와 next_post 변수가 존재하는지 확인한 후, 해당 변수가 있을 때만 링크를 표시합니다. 각 링크에는 포스트의 제목을 포함하여 사용자에게 명확한 정보를 제공합니다.


스타일링

마지막으로, 링크를 더욱 보기 좋게 스타일링할 수 있습니다. 아래는 간단한 CSS 예시입니다.

body {
    font-family: Arial, sans-serif;
}

.content {
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
}

.post-navigation {
    display: flex;
    justify-content: space-between;
    max-width: 800px;
    margin: 20px auto;
    padding: 10px;
    border-top: 1px solid #ddd;
}

.post-navigation a {
    text-decoration: none;
    color: #007BFF;
    font-weight: bold;
}

.post-navigation a:hover {
    text-decoration: underline;
}

.prev-post::before {
    content: "← ";
}

.next-post::after {
    content: " →";
}

이 스타일 시트는 링크를 좌우로 배치하고, 마우스를 올렸을 때 밑줄이 생기도록 설정합니다. 또한, 이전 글 링크 앞에는 왼쪽 화살표를, 다음 글 링크 뒤에는 오른쪽 화살표를 추가하여 직관적인 내비게이션을 제공합니다.


결론

이제 블로그 글의 상세 페이지에서 이전 글과 다음 글 링크를 자동으로 불러와서 표시할 수 있게 되었습니다. Django의 DetailView와 get_context_data 메서드를 활용하여 간단하게 구현할 수 있습니다. 이 방법을 통해 사용자에게 보다 편리한 탐색 경험을 제공할 수 있습니다.

장고 리스트