def get_board_set_from_board_group(request, board_group_id):
...완료!!!
def home(request):
...완료!!!
def board(request, board_url):
...이번장!!!
def post_detail(request, board_url, pk):
...
def reply_write(request, board_url, pk):
...
def rereply_write(request, board_url, pk):
...
def reply_delete(request, board_url, pk):
...
def rereply_delete(request, board_url, pk):
...
def like(request, board_url, pk):
...
[ get_board_set_from_board_group 함수 리팩토링 ]
get_board_set_from_board_group 리팩토링 정보 보기
[ home 함수 리팩토링 ]
home 페이지 성능 개선 Board View 코드 리팩토링
home 페이지 좋아요, 댓글 수 Board View 코드 리팩토링
Board 앱의 View 함수들을 살펴보니 총 9개의 코드가 존재합니다.
하나하나씩 불필요한 코드를 제거하거나 리팩토링해 보겠습니다
엔드포인트를 재구성하기 위해 일반 게시판, 검색 게시판, 태그 게시판에서 공용으로 사용되는 함수를 Service Layer로 분리하여 각각의 새로운 View에서 해당 로직을 사용할 수 있도록 코드 작업을 했습니다..
이제 태그 게시판을 위한 endpoint 분리를 해보겠습니다.
from django.urls import path
from .views import *
app_name = 'board'
urlpatterns = [
...
path('board/tag/<str:tag_name>', xxxxxx, name='xxxxxx'),
path('board/<str:board_url>', get_board_posts, name='get_board_posts'),
...
]
위와 같이 내용을 정리하려고 합니다.
이제 이 endpoint 에 적합한 View를 설계해서 넣어봅시다.
def get_tagged_posts(request, tag_name):
tagged_posts_request = TaggedPostsRequest.of(request)
tag = get_object_or_404(Tag, tag_name=tag_name)
paging_data = web_paging(
get_active_filtered_posts(
search=tagged_posts_request.search,
tag_names=[tag.tag_name],
).select_related(
'author'
).order_by(
'-id'
),
int(request.GET.get('page', 1)),
10,
5,
)
page_posts = paging_data['page_posts']
has_previous = page_posts.has_previous()
has_next = page_posts.has_next()
return render(
request,
'board/tagged_board_detail.html',
BoardPostsResponse(
board_detail_info=BoardDetailInfo(
name=tag_name,
info=tag_name,
url=tag_name,
),
posts=[
BoardPost(
id=post.id,
title=post.title,
short_body=post.short_body(),
board_url=post.board.url,
author_nickname=post.author.nickname,
created_at=post.created_at.strftime('%Y-%m-%d'),
like_count=post.like_count,
reply_count=post.reply_count,
image_url=post.post_img.url if post.post_img else static('logo.ico'),
) for post in page_posts
],
has_previous=has_previous,
has_next=has_next,
previous_page_number=page_posts.previous_page_number() if has_previous else None,
current_page_number=page_posts.number,
next_page_number=page_posts.next_page_number() if has_next else None,
last_page_number=page_posts.paginator.num_pages,
page_range=paging_data['page_range'],
).model_dump()
)
새로운 html 를 정의했습니다.
tagged_board_detail.html
{% extends 'base.html' %}
{% load static %}
{% block style %}
<style>
.card_img{
background-repeat:no-repeat;
background-position-y:center;
background-size:contain;
}
.truncate-3 {
font-size: 15px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
</style>
{% endblock %}
{% block title %}{{board_detail_info.name}} 태그{% endblock %}
{% block og_title %}{{board_detail_info.name}} 태그{% endblock %}
{% block description %}{{board_detail_info.info}} 태그{% endblock %}
{% block current_url %}https://cwbeany.com{{ request.get_full_path }}{% endblock %}
{% block img %}https://cwbeany.com/static/logo.ico{% endblock %}
{% block top %}
<div class="p-4 p-md-5 mb-3 rounded">
<div class="col-md-8 px-0">
<h3 class="display-4 font-monospace">#{{board_detail_info.name}}</h3>
<p class="lead my-3 font-monospace">WHAT WE TAGS {{board_detail_info.name}} LIST</p>
</div>
</div>
<!-- 글 목록 -->
<div class="row g-2 mb-4">
{% for post in posts %}
<div class="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
<a class="text-decoration-none text-dark" href="{% url 'board:post' post.board_url post.id %}">
<div class="card">
<div class="row g-0">
<div class="col-lg-8">
<div class="card-body">
<h5 class="card-title" style="white-space:nowrap;overflow: hidden;text-overflow:ellipsis;">{{post.title}}</h5>
<p class="card-text truncate-3">{{post.short_body|striptags}}</p>
<div class="card-text"><small class="text-muted"><i class="bi bi-person-circle"></i> {{post.author_nickname}}</small></div>
<div class="card-text"><small class="text-muted"><i class="bi bi-calendar-week"></i> {{post.created_at}}</small></div>
<div>
<i class="bi bi-heart text-danger"></i></i> {{post.like_count}} <i class="bi bi-chat-right-text"></i> {{post.reply_count}}
</div>
</div>
</div>
<div class="col-lg-4 card_img d-none d-lg-block rounded" style="background-image:url({{post.image_url}});">
</div>
</div>
</div>
</a>
</div>
{% endfor %}
</div>
<!-- 검색 하기 -->
<form class="d-flex mb-3" style="justify-content: flex-end;" method="get" action="">
<input class="me-2" type="text" value="{{ request.GET.search }}" name="search" placeholder="검색어를 입력하세요." />
<button class="btn btn-sm btn-primary" type="submit">검색</button>
</form>
<!-- 페이지 네이션 -->
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
{% if has_previous %}
<li class="page-item">
{% if request.GET.search %}
<a class="page-link" href="?page=1&search={{ request.GET.search }}" aria-label="First">
<span aria-hidden="true">«</span>
</a>
{% else %}
<a class="page-link" href="?page=1" aria-label="First">
<span aria-hidden="true">«</span>
</a>
{% endif %}
</li>
<li class="page-item">
{% if request.GET.search %}
<a class="page-link" href="?page={{ previous_page_number }}&search={{ request.GET.search }}" aria-label="Previous">
<span aria-hidden="true"><</span>
</a>
{% else %}
<a class="page-link" href="?page={{ previous_page_number }}" aria-label="Previous">
<span aria-hidden="true"><</span>
</a>
{% endif %}
</li>
{%endif%}
{% for i in page_range %}
{% if i == current_page_number %}
{% if request.GET.search %}
<li class="page-item active"><a class="page-link" href="?page={{i}}&search={{ request.GET.search }}">{{i}}</a></li>
{% else %}
<li class="page-item active"><a class="page-link" href="?page={{i}}">{{i}}</a></li>
{% endif %}
{% else %}
{% if "search=" in request.get_full_path %}
<li class="page-item"><a class="page-link" href="?page={{i}}&search={{ request.GET.search }}">{{i}}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{i}}">{{i}}</a></li>
{% endif %}
{% endif %}
{% endfor %}
{% if has_next %}
<li class="page-item">
{% if request.GET.search %}
<a class="page-link" href="?page={{ next_page_number }}&search={{ request.GET.search }}" aria-label="Next">
<span aria-hidden="true">></span>
</a>
{% else %}
<a class="page-link" href="?page={{ next_page_number }}" aria-label="Next">
<span aria-hidden="true">></span>
</a>
{% endif %}
</li>
<li class="page-item">
{% if request.GET.search %}
<a class="page-link" href="?page={{ last_page_number }}&search={{ request.GET.search }}" aria-label="Last">
<span aria-hidden="true">»</span>
</a>
{% else %}
<a class="page-link" href="?page={{ last_page_number }}" aria-label="Last">
<span aria-hidden="true">»</span>
</a>
{% endif %}
</li>
{%endif%}
</ul>
</nav>
{% endblock %}
[Request, Response DTO Github 코드]
결과는 아래와 같습니다~
SQL 도 보면 9개의 SQL 이 조회됩니다.
이전에는 어떻게 조회가 됐을까요?
SQL이 26개나 있었습니다. 엄청난 개선을 했습니다~!