책 리뷰 페이지 03

·2023년 10월 11일
0

웹 프로젝트

목록 보기
7/18

이번엔 프론트엔드를 작업할 차례다.

우선 태그 클라우드를 출력할 기본 html을 만든다.

<!-- 태그 클라우드를 보여주는 템플릿 파일 -->
{% extends 'base.html' %}

{% load static %}

{% block title %}taggit_cloud.html{% endblock %}

{% block script %} 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="{% static 'main.js' %}"></script>
{% endblock %}

{% block extra-style %}
<style type="text/css">
    .tag-cloud {
        width: 40%;
        margin-left: 30px;
        text-align: center;
        padding : 5px;
        border: 1px solid orange;
        background-color: #ffc;
    }
    .tag-1{font-size: 12px;}
    .tag-2{font-size: 14px;}
    .tag-3{font-size: 16px;}
    .tag-4{font-size: 18px;}
    .tag-5{font-size: 20px;}
    .tag-6{font-size: 24px;}
</style>
{% endblock %}

{% block content %}
    <h1>Blog Tag Cloud</h1>
    <br>
    <div id="books">
        
    </div>
    <div class="tag-cloud">
        {% load taggit_templatetags2_tags %}
        {% get_tagcloud as tags %}
        {% for tag in tags %}
        <span class="tag-{{tag.weight|floatformat:0}}">
            <a href="{% url 'tagged_object_list' tag.name %}">{{tag.name}}({{tag.num_times}})</a>
        </span> <!--tag.name 인자를 넘겨 지정 -->
        {% endfor %}
    </div>
{% endblock %}

이번에는 js 를 쓸 예정이기 때문에 {% load static %}으로 static 을 로드한 뒤 script src 에 {% static 'main.js' %} 을 써줬다. 절대 경로로 쓰면 앞에 localhost 가 붙기 때문에 상대경로로 써줘야 한다.

  • settings.py 에 STATIC_DIR 설정 해주는 것도 잊지 말자

static/main.js 는 파일 변경 후 적용을 위해 python3 manage.py collectstatic 를 쳐줘야 한다.

static/main.js



window.onload = () => {
    BookView()
}

// 메인페이지
async function BookView() {

    const response = await fetch('http://127.0.0.1:8000/book/mainpage/', {
        method: 'GET',
    })
    response_json = await response.json()

    books = response_json.data[0]

    books.forEach(element => {
        temp_html = `<div>
            ${JSON.stringify(element['title'])}
            <img src="/media/${element.cover}">
        </div>`
        $('#books').append(temp_html)

        console.log(element)
    });

    // console.log(response_json.data[0])  // 책
    // console.log(response_json.data[1])  // 리뷰
    // console.log(response_json.data[2])  // 태그
}
  • JSON.stringfy() 를 해주지 않으면 objects Object 로 출력되므로 잊지 말고 해주자
  • ${element.cover} 앞에 /media/ 를 붙여주어야 서버가 media 폴더를 찾는다. 난 처음에 경로를 그냥 / 로 적어놓고 media 가 맞는데... 하다가 book.cover.url 을 출력해보고서야 경로를 알았다.

views.py 에서 좋아요가 많은 순서대로 책을 출력해주려고 했는데 likes 를 ManyToManyField 로 선언해놓고 그걸로 order by 를 하는 바람에 데이터가 중복 출력되는 오류가 있었다. Count() 를 통해 아래와 같이 고친 뒤 제대로 작동하는 것을 확인했다.

book/views.py

def get(self, request):
        # 추천 책
        books = (
            Book.objects.all()
            .annotate(likes_cnt=Count("likes"))
            .order_by("likes_cnt")
            .distinct()
            .values()
        )

        # values() 를 했기 때문에 값이 그대로 전달되지 않음 > serializerMethod 를 추가
        serializer = BookSerializer(books, many=True)

        # 인기 리뷰
        reviews = (
            Review.objects.all()
            .annotate(likes_cnt=Count("likes"))
            .order_by("likes_cnt")
            .values()
        )

        re_serializer = ReviewSerializer(reviews, many=True)

        # 태그
        tags = Tag.objects.all()
        # print(tags)
        tag_serializer = TagSerializer(tags, many=True)

        serializer_list = [serializer.data, re_serializer.data, tag_serializer.data]

        content = {
            "status": 1,
            "responseCode": status.HTTP_200_OK,
            "data": serializer_list,
        }

        return Response(content)
profile
공부 중

0개의 댓글