[STEP 8] 디테일 업그레이드 (조회수 쿠키 & Humanize)
본 카테고리의 마지막 단계입니다.
조회수 중복 증가(F5 연타)를 방지하고, "방금 전", "5분 전" 같은 날짜 표시를 적용합니다.
1. 설정 추가 (config/settings.py)
config/settings.py 를 열어 날짜를 사람이 보기 편하게 바꿔주는 humanize 앱을 등록합니다.
INSTALLED_APPS = [
# ... 기존 앱들 ...
'django.contrib.staticfiles',
'django.contrib.humanize', # [추가]
# ...
]
# (참고) 언어 설정이 한국어여야 "방금 전"으로 나옵니다.
LANGUAGE_CODE = 'ko-kr'
⚠️ 중요: 서버가 실행 중이라면 설정 파일을 수정했으므로 서버를 재시작해 주세요.
2. 로직 수정 (boards/views.py)
쿠키(Cookie)를 사용하여 "오늘 하루 동안은 같은 글의 조회수를 1번만 증가"시키도록 로직을 변경합니다.
boards/views.py의 board_detail 함수를 수정하세요.
# [import 추가]
from django.utils import timezone
from datetime import datetime, timedelta, time
def board_detail(request, board_code, pk):
board = get_object_or_404(Board, code=board_code)
post = get_object_or_404(Post, pk=pk, board=board)
# 1. 쿠키 이름 정의 (게시글마다 달라야 함)
cookie_name = f'hitboard_{board_code}_{pk}'
# 2. 응답 객체 미리 생성 (쿠키를 심기 위해)
# select_related('author'): 댓글 작성자 정보를 한 번에 가져와서 DB 성능 최적화
response = render(request, 'boards/board_detail.html', {
'board': board,
'post': post,
'comments': post.comments.select_related('author').all(),
'form': CommentForm()
})
# 3. 쿠키 확인: 쿠키가 없을 때만 조회수 증가
if request.COOKIES.get(cookie_name) is None:
post.views += 1
post.save()
# 4. 쿠키 유효기간 설정 (오늘 밤 자정까지)
tomorrow = datetime.now() + timedelta(days=1)
midnight = datetime.combine(tomorrow, time.min)
expires = (midnight - datetime.now()).total_seconds()
# 쿠키 심기
response.set_cookie(cookie_name, 'true', max_age=expires)
return response
3. 화면 수정 1 - 메인 대시보드 (templates/home.html)
메인 화면(templates/home.html)의 게시글 목록에 작성 시간(naturaltime)을 추가합니다.
{% extends 'base.html' %}
{% load humanize %} {% block content %}
<div class="row mt-2">
<div class="col-md-6 mb-4">
<div class="card h-100">
<div class="card-header bg-light">
<i class="bi bi-clock"></i> <strong>자유게시판 최신글</strong>
</div>
<ul class="list-group list-group-flush">
{% for post in free_posts %}
<li class="list-group-item d-flex justify-content-between align-items-center">
<a href="{% url 'boards:board_detail' post.board.code post.pk %}" class="text-decoration-none text-dark text-truncate" style="max-width: 75%;">
{{ post.title }}
<span class="small text-muted ms-1">
{{ post.created_at|naturaltime }}
</span>
</a>
<div class="small text-muted">
{{ post.author.username }}
</div>
</li>
{% empty %}
<li class="list-group-item text-center text-muted small py-3">등록된 게시글이 없습니다.</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endblock %}
💡 naturaltime이 자동으로 해주는 것
{{ post.created_at|naturaltime }} 한 줄을 적으면, 내부적으로 이런 계산을 수행합니다.
- 현재 시간(Now)과 입력된 시간(Created_at)의 차이를 계산합니다.
- 그 차이에 따라 적절한 문자열을 리턴합니다.
- 몇 초 차이: "방금 전 (now)"
- 몇 분 차이: "3분 전 (3 minutes ago)"
- 몇 시간 차이: "2시간 전 (2 hours ago)"
- 하루 이상: "어제 (yesterday)", "3일 전", "1달 전"
4. 화면 수정 2 - 게시글 상세 (boards/board_detail.html)
게시글 상세 화면(boards/board_detail.html)에서 게시글과 댓글 작성 시간에도 적용합니다.
{% extends 'base.html' %}
{% load humanize %} {% block content %}
<span class="text-muted small ms-2">{{ post.created_at|naturaltime }}</span>
<span class="text-muted small ms-2">{{ comment.created_at|naturaltime }}</span>
{% endblock %}
5. 화면 수정 3 - 쪽지함 (accounts/message_list.html)
쪽지함 (accounts/message_list.html)의 쪽지 수신 시간에도 적용합니다.
{% extends 'base.html' %}
{% load humanize %} {% block content %}
<small class="text-muted">{{ msg.created_at|naturaltime }}</small>
{% endblock %}
6. 테스트
- 조회수 방지: 게시글 접속 후 F5를 눌러도 조회수가 그대로인지 확인합니다.
- 시간 표시: "방금 전", "5분 전" 등으로 예쁘게 나오는지 확인합니다.
'Step by Step > [phase 2] django community upgrade' 카테고리의 다른 글
| Bonus Book 2. Django Admin 커스터마이징 (0) | 2025.12.09 |
|---|---|
| Bonus Book 1. 게시판 관리자(Staff) 권한 부여 (0) | 2025.12.09 |
| 7. 사용자 간 1:1 쪽지 기능(DM) 구현 (0) | 2025.12.07 |
| 6. 회원 프로필(닉네임 & 아바타) (0) | 2025.12.07 |
| 5. 메인 페이지(대시보드 & 데이터 조회) 구현 (0) | 2025.12.07 |