2022.11.02 TIL

동찌·2022년 11월 2일
0

내일배움단

목록 보기
3/56
post-custom-banner

오늘의 할일

  • 방명록 삭제, 수정 기능 구현하기
  • 각 페이지마다 방명록 구현
  • 메인페이지 구현, 사이트에 들어갈 기능 회의

방명록 삭제, 수정 기능 구현


방명록 삭제

웹개발종합반에서 배웠던 내용중에 버킷리스트 완료기능을 구현하는게 있어서 그걸 응용하면 될 것 같아 강의를 다시 들었다.

강의에서는 버킷리스트를 완료하면 버킷리스트에 취소선이 생기도록 db.update_one을 사용했는데, 삭제는 delete_one을 사용하면 될 것 같아 구현에 성공했다.

  • 우선 기존 서버에서 POST형식으로 데이터를 받아 저장할 때 db의 갯수를 카운팅 하기위해 num값을 넣어줬다.
  • num 데이터를 받는 함수는 따로 써준다.
  • 파이썬은 문자열로 데이터를 받아오기 때문에 int()를 써서 숫자로 바꿔준다.
  • GET은 언제나 그렇듯이 조회하는 것이기 때문에 데이터를 불러준다.
@app.route('/guests', methods=["POST"])
def guest_post():
    guest_name_recive = request.form['guest_name_give']
    guest_comment_recive = request.form['guest_comment_give']
	
    #저장된 데이터를 불러온 후, 저장된 데이터 개수 + 1을 하여 넘버링
    guest_list = list(db.guests.find({}, {'_id': False}))
    count = len(guest_list) + 1
	
    doc = {
        'name' : guest_name_recive,
        'comment' : guest_comment_recive,
        'num' : count
    }

    db.guests.insert_one(doc)

    return jsonify({'msg': '응원 감사합니다!'})
    
@app.route("/guests/remove", methods=["POST"])
def guest_remove():
    num_recive = request.form['num_give']

    db.guests.delete_one({'num': int(num_recive)})

    return jsonify({'msg': '삭제되었습니다.'})
    
@app.route("/members", methods=["GET"])
def member_get():

    member_list = list(db.members.find({}, {'_id': False}))

    return jsonify({'members': member_list})
  • 클라이언트 쪽에서 받을 데이터는 방명록을 받을 함수와 삭제를 위한 num데이터를 받을 함수를 나누어 써준다.
  • 삭제 버튼에 들어갈 함수를 추가해줬다.
function save_guest(){
    let guest_name = $('#guest-name').val()
    let guest_comment = $('#guest-comment').val()

    $.ajax({
        type: "POST",
        url: "/guests",
        data: {guest_name_give: guest_name, guest_comment_give: guest_comment},
        success: function(response){
            alert(response['msg'])
            window.location.reload()
        }
    })
}

function show_guest(){
    $.ajax({
        type:"GET",
        url:"/guests",
        data:{},
        success: function(response){
            let guest_rows = response["guests"]
            for(let i = 0; i < guest_rows.length; i++){
                let guest_name = guest_rows[i]['name']
                let guest_comment = guest_rows[i]['comment']
                let num = guest_rows[i]['num']

                let temp_html = `<li>
                                    <div class="guest-name">${guest_name}</div>
                                    <div class="guest-comment">${guest_comment}</div>
                                    <div class="guest-btn-wrap">
                                        <div class="btn-group btn-group-sm" role="group" aria-label="Basic example">
                                            <button type="button" class="btn btn-outline-dark">수정</button>
                                            <button type="button" onclick="remove_guest(${num})" class="btn btn-outline-dark">삭제</button>
                                        </div>
                                    </div>
                                </li>`

                $('#guest-list').append(temp_html)
                console.log(guest_rows)
            }
        }
    })
}
function remove_guest(num){
    $.ajax({
        type: "POST",
        url: "guests/remove",
        data: {num_give: num},
        success: function (response){
            alert(response["msg"])
            window.location.reload()
        }
    })
}

방명록 수정

머리가 도저히 안굴러가서 오랜만에 노트에 메모하면서 생각해봤다.

대충 의식의 흐름대로 막 휘갈겨봤는데 정리하자면

  1. 수정을 하려면 일단 POST 형식임
  2. 수정 버튼을 눌렀을 때 해당 글의 내용(guest_comment)이 input으로 바뀌어야 하고 완료버튼만 있게 해야함. -> 이 부분은 GET방식에서 temp_html을 조건문을 사용하여 변경해야함
  3. 그럼 수정 버튼을 눌렀을 때 2번에 쓴 것처럼 조건문을 만들고 돌아가게 하려면 change = 0을 저장해놓고 눌렀을 때 1로 바뀌게 해야하니깐 update_one을 이용해서 바꿔줘야함
  4. 그럼 수정 완료 버튼을 눌렀을 때에는 바뀐 내용을 저장하고 change를 다시 0으로 해야하니깐 update_one을 또 사용해서 함수를 만들어야함

정리가 안된 것 같지만 그래도 이걸 토대로 만들어본다.

구현이 되었다? 왜 됐지?
til쓰면서 곱씹어 보자

  • 우선 서버 쪽 코드이다.
    넘버링 한 데이터를 집어서 수정을 해야하기 때문에 num을 받는다.
    처음에 코드를 하나만 썼는데, 그러면 수정 완료가 안되고 만들어놓은 input과 버튼만 덩그러니! 그래서 change의 숫자를 기본 0으로하고 1, 2로 업데이트 해줬다.
    그런데 til 쓰기 전에 input값 받는 코드를 안썼다.
    끝까지 잘 되는지 안되는 부분은 없는지 꼼꼼히 체크하는 습관을 들이자.
@app.route("/guests/change", methods=["POST"])
def guest_change():
    num_recive = request.form['num_give']

    db.guests.update_one({'num': int(num_recive)}, {'$set': {'change': 2}})

    return jsonify({'msg': '수정 하시겠습니까?'})

@app.route("/guests/change_done", methods=["POST"])
def guest_change_done():
    num_recive = request.form['num_give']
    change_guest_comment_recive = request.form['change_guest_comment_give']

    db.guests.update_one({'num': int(num_recive)}, {'$set': {'change': 1, 'comment': change_guest_comment_recive}})

    return jsonify({'msg': '수정 완료!'})
  • 클라이언트 쪽 js
    우선 GET방식에서 change의 값도 가져온다.
    그러고 조건문을 써서 change값이 2일 때 수정할 수 있는 input과 완료버튼을 넣어준다. input에는 원래 자신이 썼던 글을 value에 남겨줬다.
    else는 til을 쓰며 생각해보니 같은 내용을 왜 두번 썼지
    or을 써서 바꿔줬다.
    change_done()에서 바뀐 내용을 받아 넘겼다.
function show_guest(){
    $.ajax({
        type:"GET",
        url:"/guests",
        data:{},
        success: function(response){
            let guest_rows = response["guests"]
            for(let i = 0; i < guest_rows.length; i++){
                let guest_name = guest_rows[i]['name']
                let guest_comment = guest_rows[i]['comment']
                let num = guest_rows[i]['num']
                let change = guest_rows[i]['change']

                let temp_html = ``

                //if(change == 0){
                //     temp_html = `<li>
                //                     <div class="guest-name">${guest_name}</div>
                //                     <div class="guest-comment">${guest_comment}</div>
                //                     <div class="guest-btn-wrap">
                //                         <div class="btn-group btn-group-sm" role="group" aria-label="Basic example">
                //                             <button type="button" class="btn btn-outline-dark" onclick="change_guest(${num})">수정</button>
                //                             <button type="button" onclick="remove_guest(${num})" class="btn btn-outline-dark">삭제</button>
                //                         </div>
                //                     </div>
                //                 </li>`
                // }else if(change == 2){
                //     temp_html = `<li>
                //                     <div class="guest-name">${guest_name}</div>
                //                     <div class="guest-comment"><input type="text" id="change_guest_comment" value="${guest_comment}"></div>
                //                     <div class="guest-btn-wrap">
                //                         <button type="button" class="btn btn-outline-dark" onclick="change_guest_done(${num})">완료</button>
                //                     </div>
                //                 </li>`
                // }else{
                //     temp_html = `<li>
                //                     <div class="guest-name">${guest_name}</div>
                //                     <div class="guest-comment">${guest_comment}</div>
                //                     <div class="guest-btn-wrap">
                //                         <div class="btn-group btn-group-sm" role="group" aria-label="Basic example">
                //                             <button type="button" class="btn btn-outline-dark" onclick="change_guest(${num})">수정</button>
                //                             <button type="button" onclick="remove_guest(${num})" class="btn btn-outline-dark">삭제</button>
                //                         </div>
                //                     </div>
                //                 </li>`
                // }
                if(change == 0 || change == 1){
                    temp_html = `<li>
                                    <div class="guest-name">${guest_name}</div>
                                    <div class="guest-comment">${guest_comment}</div>
                                    <div class="guest-btn-wrap">
                                        <div class="btn-group btn-group-sm" role="group" aria-label="Basic example">
                                            <button type="button" class="btn btn-outline-dark" onclick="change_guest(${num})">수정</button>
                                            <button type="button" onclick="remove_guest(${num})" class="btn btn-outline-dark">삭제</button>
                                        </div>
                                    </div>
                                </li>`
                }else{
                    temp_html = `<li>
                                    <div class="guest-name">${guest_name}</div>
                                    <div class="guest-comment"><input type="text" id="change_guest_comment" value="${guest_comment}"></div>
                                    <div class="guest-btn-wrap">
                                        <button type="button" class="btn btn-outline-dark" onclick="change_guest_done(${num})">완료</button>
                                    </div>
                                </li>`
                }
                $('#guest-list').append(temp_html)
                console.log(guest_rows)
            }
        }
    })
}

function change_guest(num){
    $.ajax({
        type: "POST",
        url: "guests/change",
        data: {num_give: num},
        success: function (response){
            alert(response["msg"])
            window.location.reload()
        }
    })
}
function change_guest_done(num){
    let change_guest_comment = $('#change_guest_comment').val()

    $.ajax({
        type: "POST",
        url: "guests/change_done",
        data: {num_give: num, change_guest_comment_give: change_guest_comment},
        success: function (response){
            alert(response["msg"])
            window.location.reload()
        }
    })
}

TIL을 쓰지 않았다면 오늘 구현 다 했다고 해놓고 내일 틀린부분을 찾아서 오열하며 코드를 다시 짰겠지... 고맙다 TIL아!

메인페이지 구현, 사이트에 들어갈 기능 회의


메인페이지

메인페이지는 아래사진처럼 단체사진을 클릭하면 텍스트가 뜨도록 만들기로 했다.
텍스트는 가운데 정렬로 바꿀 것이고, 클릭 전에는 뭔가 사람들이 클릭할 수 있는걸 알 수 있는 트리거를 만들 것이다.

귀찮아서 대충 버튼 달았다.

클릭하면 목표와 약속이 보이도록 했다.
그런데 처음에 button태그를 쓰고 함수에 innerText를 사용했는데 VIEW INFO 부분이 바뀌지가 않아서 그냥 input태그의 value를 바꾸었다.
왜 안되는지 모르겠지만 4시30분까지 만들기로 해서 미련을 버리고 공유했다.

그러나 중요한 것은 flask에서 페이지 연결을 어떻게 하는지 모르겠다는 것이다.
검색해보니 내일배움단 이전 기수분들이 til에 써놓은 블로그가 있었다. 그거를 보고 따라했는데 나는 왜 안되는거야.ㅠ
멘탈이 살짝 나가서 쉬는김에 til을 쓰고있다.

내가 이겼다 컴퓨터놈아
번역기돌려서 영어로 검색하니까 나왔다 히히히히히

@app.route('/team')
def team():
   return render_template('team.html')

html을 불러와서 url을 설정해주고

<a href={{url_for('team')}}>

To define the hyperlinks in Flask, Jinja template language is used for rendering pages requested by users. The parameter defined with the functions linked with routes can be passed to the requested page using Jinja template language. Such variables from application can be sent to page by by enclosing it in double curly parenthesis {{}}.
출처 : https://csveda.com/python-flask-website-adding-routes-to-link-pages/

jinja 템플릿 언어를 사용하여 요청한 페이지에 전달할 수 있다고 한다.
번역기가 말해줘서 정확히 무슨 뜻인지는 모르겠는데 암튼 그렇다 대단하다!
역시 구글링은 영어로!

사이트에 들어갈 기능

첫 날 얘기한대로 일단 필수 기능만 구현하기로 했다.
방명록 작성, 조회
삭제 기능은 해결했으니 아마 삭제기능까지는 넣을 것 같다.
DB로 팀원소개페이지에 팀원 내용을 저장하고 가져오려고 했는데, 각자 소개페이지를 만들기 때문에 어려움이 있을 것 같다.
이 부분은 페이지 완성 후에 생각해봐야 할 것 같다.


ox퀴즈, 마라톤 그리고 보물찾기...

재미있었다. 역시 노는건 시간이 순삭이다.
ox퀴즈는 버그가 많아서 첫판에 혼자 남았는데 아무것도 없을 것 같다...허허
html은 프로그래밍 언어 아닌데...(A형에 I라 담아둠 쒸익쒸익)
그래도 마라톤 순위권 한번 들고 보물찾기도 나름 빨리 올렸으니 개꿀이다.
이런 귀여운 이벤트 너무 좋다 ㅎㅎ

오늘의 일기

항상 자만하지말고 컴퓨터는 처음부터 끝까지 떠먹여줘야 아니까 순차적으로 잘 생각하면서 코딩을 하자.
구선생님은 의심하지말고 원하는 내용이 검색이 안될 때는 번역기를 돌려서 검색하자.
그리고 오늘 힘들어서(귀찮아서 아님 벌써 10시임 진짜임) 수정하는 input css 안 건드렸는데 내일은 좀 건드리자.
페이지 연결하는 법 알았으니까 내일은 그거 연결해보자.
세상 공부하는 사람들 모두 화이팅...!

post-custom-banner

1개의 댓글

comment-user-thumbnail
2022년 11월 3일

노트도 필기하시고 정리도 깔끔하시고 ㅎㅎ너무 멋집니다
생각하는 힘을 기르시면 앞으로도 정말 많은 도움 되실것 같네요
화이팅!

답글 달기