본격 개발! 9일차

박지환·2022년 5월 16일
0

본격 개발!

목록 보기
8/8
post-thumbnail

메인 페이지 작업

다음으로 할 작업은 두 가지이다.
1) 메인 페이지의 캐릭터 카드를 DB에서 가져와서 자동으로 생성하고,
2) 캐릭터 카드랑 개별 캐릭터의 상세 페이지를 잇는 것.

캐릭터 카드 자동생성

스파르타 웹개발종합반 강의에서 여러 번 해봤던 거라 쉽게 생각했는데,
강의 자료랑 강의 영상을 참고해서 카드를 생성하는데 생각보단 진도가 잘 안 나갔다.

그래도 어찌어찌 배운대로 카드를 붙였다.

main.html

        // 카드 생성 함수
        function showCards() {
            $.ajax({
                type: "GET",
                url: "/card",
                data: {},
                success: function (response) {
                    let card = response['all_cards']
                    for (let i = 0; i < card.length; i++) {
                        let name = card[i]['name']
                        let portrait = card[i]['portrait']
                        let score = card[i]['score']
                        let group = card[i]['group']

                        let temp_html = `<div class="give_id col-3 col-sm-3 col-md-2 mt-1">
                                            <div class="Bot_tier">
                                                <div class="portrait embed-responsive embed-responsive-1by1">
                                                    <img src="${portrait}"
                                                         class="card-img-top embed-responsive-item img-fluid" alt="Responsive image">
                                                </div>
                                                <div class="name blockquote text-center">
                                                    ${name}

                                                    <div>
                                                        <i class="fa fa-star checked" style="font-size: medium"></i>
                                                        <i class="fa fa-star checked" style="font-size: medium"></i>
                                                        <i class="fa fa-star checked" style="font-size: medium"></i>
                                                        <i class="fa fa-star checked" style="font-size: medium"></i>
                                                        <i class="fa fa-star-o fa-lg checked" style="font-size: medium"></i>
                                                    </div>
                                                    <span>점수: ${score}</span>
                                                </div>

                                            </div>
                                        </div>`

                        $('#cards-box').append(temp_html)
                    }
                }
            })
        }

app.py

# 카드 생성
@app.route('/card', methods=['GET'])
def listing():
    cards = list(db.characterpost.find({}, {'_id': False}))
    return jsonify({'all_cards': cards})

캐릭터 카드를 클릭하면 캐릭터 상세페이지로 이동

이쪽이 머리가 아팠다.
처음에는 모든 캐릭터 DB에 대해서 웹페이지를 만들어두고 카드를 누르면 불러오는 식으로 만들어야 하나 생각했다.
그런데 이렇게하면 미리 DB를 다 만들어둬야 하니까 더 무거워지는 건 아닌가 하는 생각이 들었다.

그래서 어떻게하면 더 가볍게 만들 수 있을까 생각해봤는데,
소개페이지의 틀은 그대로 두고(액자처럼) 그때그때 DB에서 정보를 불러와서(그림만 바꿔끼우는 것처럼) 보여주는 방법을 쓰면 되겠다는 생각이 들었다.

여기서 생기는 두 가지 문제

1) 캐릭터 카드를 클릭할 때 어떻게 캐릭터를 특정할까
2) 특정된 캐릭터를 어떻게 DB랑 이어줄 수 있을까

캐릭터를 특정짓기

캐릭터 이름 id부여

temp_html에 첫번째 div에 각 캐릭터의 이름을 id로 주려고 했는데 한 시간 동안이나 끙끙대다가 결국 못했다.

for문이 돌아가면서 i번째 데이터마다 각각 id를 바꿀 수 있게 .attr()도 써봤는데 맨 마지막의 캐릭터 이름을 모두가 id로 가지게 되어서 실패했다.

한 시간을 넘게 못 풀고 있는데 아내가 왔길래 상황을 설명해줬다.
temp_html에서 다른 형태의값처럼idid="{} 형태의 값처럼 id도 id="{name}" 형태로 추가하면 될 것 같다고 해서 넣어봤더니 해결됐다.
하하... 사수가 있어야 일이 수월하다.

let temp_html = `<div class="give_id col-3 col-sm-3 col-md-2 mt-1">
                                            <div class="Bot_tier">
                                                <div class="portrait embed-responsive embed-responsive-1by1">
                                                    <img id="${name}"  src="${portrait}"
                                                         class="card-img-top embed-responsive-item img-fluid" alt="Responsive image">
                                                </div>
                                                <div class="name blockquote text-center">
                                                    ${name}

                                                    <div>
                                                        <i class="fa fa-star checked" style="font-size: medium"></i>
                                                        <i class="fa fa-star checked" style="font-size: medium"></i>
                                                        <i class="fa fa-star checked" style="font-size: medium"></i>
                                                        <i class="fa fa-star checked" style="font-size: medium"></i>
                                                        <i class="fa fa-star-o fa-lg checked" style="font-size: medium"></i>
                                                    </div>
                                                    <span>점수: ${score}</span>
                                                </div>

                                            </div>
                                        </div>`

클릭된 id(캐리터 이름)를 서버에 전달하기

클릭한 id를 변수로 가져가는 것부터 머리가 아프다.
시간을 들여 예제 코드를 찾고 따라해보고 넣어서 해보니 된다.

main.html

// id를 매개변수로 가져가는 코드

        function reply_click(clicked_name){
            let cl_name = clicked_name

            // name을 name_click에 넣고 서버로 보내는 부분
            $.ajax({
                type: "POST",
                url: "/inform",
                data: {
                    name_clicked: cl_name
                },
                success: function (response) {
                    window.location.href = 'http://localhost:5000/intro'
                }
            })
        }

이제 클릭한 캐릭터의 이름을 서버가 받고, 그 캐릭터의 DB를 캐릭터 소개페이지로 넘겨주면서 캐릭터 소개페이지를 열면 된다.

그런데... 안된다...

이 부분이 지금까지 이 웹페이지를 만드는 과정 중에 가장 힘든 과정이었다.

5시간은 해결을 못하고 끙끙댔다.
이렇게도 해보고 저렇게도 해보고...
아무리 구글을 찾아도 눈에 확들어오는 글이 없다.

이론이 부족해서 생긴 문제라고 느껴졌다.
ajax가 어떤 도구인지 정확하게 몰라서 제대로 못 쓴다는 생각이 들었다.
GET, POST를 서버에서 정보를 받아올 때, 정보를 수정할 때 쓴다는 내용만 대충 알았지 어떤 원리로 어떻게 돌아가는지를 몰랐다.

데코레이터가 뭔지, 메소드가 뭔지도 모른다.
ajax의 원리와 기본적인 용어를 공부해야할 필요성을 느꼈다.

구글에서 찾다보니 내가 원하는 기능은 분명 POST와 GET을 한번에 써야하는데 대부분의 글은 POST와 GET을 따로 써야한다고 이야기하고 있었다.(기능, 보안 상의 이유 등으로?)

그럼 하나의 데코레이터에서 두 개의 함수를 써야하는 것인지,
하나의 함수에서 if문으로 제어를 하면 되는 것인지 여러 시도를 해봤다.

그런데 if문을 쓰든 두 개의 함수를 쓰든 클릭해서 받아온 캐릭터 이름을 else나 다른 함수에선 기억하지 못했기 때문에 문제가 해결되지 않았다.

그래서 받아온 이름을 저장한 변수를 다른데서 써야한다는 생각이 들었고 전역변수를 써서 문제를 해결했다.

이 문제를 해결하려고 글을 읽어보면서 전역변수 또한 쓰지 않는 것이 좋다는 이야기를 많이 보았는데 어쩔 수가 없었다.
전역변수도 잘 관리해서 쓰면 되지 않을까?

app.py

# 캐릭터소개 페이지 연결
# 더럽게 안 됐는데 전역변수랑 elif 써서 성공
@app.route('/inform', methods=['POST', 'GET'])
def get_name():
    global name_selected
    if request.method == 'POST':
        name_selected = request.form['name_clicked']
        return jsonify({'msg':'이것은 name POST!'})
    elif request.method == 'GET':
            information = db.characterpost.find_one({'name': name_selected}, {'_id': False})
            return jsonify({'character_selected': information})

사진이랑 유튜브는 아직 핑크퐁으로 되어있다.

따라서 다음은 사진이랑 유튜브 웹스크래핑 작업을 할 차례이다.

profile
시작은 창대하나 끝은 미약하리라

0개의 댓글