회원가입

[리팩토링] 11. (2) board 함수 리팩토링 태그 게시판 View 재구성

Beany 2024-06-16

 AS-IS Code

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개의 코드가 존재합니다.
하나하나씩 불필요한 코드를 제거하거나 리팩토링해 보겠습니다


 

태그 게시판에 대한 로직을 새로운 endpoint 로 재구성

엔드포인트를 재구성하기 위해 일반 게시판, 검색 게시판, 태그 게시판에서 공용으로 사용되는 함수를 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">&laquo;</span>
                </a>
            {% else %}
                <a class="page-link" href="?page=1" aria-label="First">
                    <span aria-hidden="true">&laquo;</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">&lt;</span>
                </a>
            {% else %}
                <a class="page-link" href="?page={{ previous_page_number }}" aria-label="Previous">
                    <span aria-hidden="true">&lt;</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">&gt;</span>
            </a>
        {% else %}
            <a class="page-link" href="?page={{ next_page_number }}" aria-label="Next">
                <span aria-hidden="true">&gt;</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">&raquo;</span>
            </a>
        {% else %}
            <a class="page-link" href="?page={{ last_page_number }}" aria-label="Last">
                <span aria-hidden="true">&raquo;</span>
            </a>
        {% endif %}
        </li>
        {%endif%}
    </ul>
</nav>
{% endblock %}

 

[Request, Response DTO Github 코드]

 

 

결과는 아래와 같습니다~

SQL 도 보면 9개의 SQL 이 조회됩니다.

 

이전에는 어떻게 조회가 됐을까요?

SQL이 26개나 있었습니다. 엄청난 개선을 했습니다~!

0 0
블로그 일기
제 블로그의 고도화 과정을 설명합니다. 이는 코드 리팩토링과 추가된 기능들에 대해 기록하기 위한 게시판입니다. 어떤 기능이 추가되었는지, 무엇이 개선되었는지 등 고도화되는 과정을 자세히 다룰 예정입니다.
Yesterday: 456
Today: 130