본문 바로가기

WIL

내일배움캠프 4기_미니프로젝트 1주차 WIL

728x90

내일배움캠프 4기_미니프로젝트 일주차 WIL


미니프로젝트 아쉬운 점, 좀 더 공부해 볼 내용.


📌 API CRUD기능

아무래도 FrontEnd 와 BackEnd를 동시에 진행하다보니 보여지는 면에 시간을 많이 투자하게 되었습니다.
그래서 BackEnd의 기본적인 API CRUD기능 구현에 시간을 투자하지 못한 부분이 아쉽게 느껴졌습니다.

수정&삭제를 구현하기위해 방명록 HTML태그마다 고유값을 부여해 줘야 한다는 점도 실제로 구현하고 나서야 알게되었습니다. 고유값을 어떻게 줘야하는지 좀 더 심도 있게 고민했었더라면, 더욱 완성도 높았을 텐데. 이 점 아쉽습니다.

저는 처음에 삭제기능을 내일배움단에서 배웠던 num으로 접근하니, 여러 테스트 케이스에서 제대로 작동하지 않아 버킷리스트 프로젝트 click키값으로 접근해 html상 보여지는 부분에서만 삭제된 것처럼 보이게 구현했었습니다.
즉, DB에서는 삭제된게 아닌거죠!
그래서 이부분을 튜터님의 조언을 들어보기도 하고 고유값을 줘야 한다는 점도 프로젝트 발표 전날 알게되었다.


📌 조원검색기능

이름, 색깔(각 조원이 맡은 색깔), 개인페이지html
3가지 정보를 DB에 넣어 회원 검색 기능을 넣어봤습니다.
다시 공부하기 위해 코드를 보니 굳이 boolean값(flag 변수)을 왜 사용했는지 의문이네요...
이 기능이 새로고침할 때마다 작동하지 않는 문제가 있었습니다.

됐다 안됐다...
이 부분의 원인을 생각해보려 했지만, 잘 모르겠어서 많이 아쉬웠습니다.
조원분 한분이 이 문제에 대해 고민해보시더니, 프로젝트 발표날 밤에 슬랙에 올려주셔서 저도 공부해봤습니다.
처음 보는 쿼리 스트링? 이 부분이 뭔지. 주말에 추가로 공부해 봤습니다.


API

📌 CRUD

Create Read Update Delete
POST GET PUT DELETE
insert Select Update Delete


📄 app.py

from flask import Flask, render_template, request, jsonify
app = Flask(__name__)

from time import time

from pymongo import MongoClient
client = MongoClient('본인 db저장소 주소')
db = client.dbsparta

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

@app.route("/homework/click", methods=["DELETE"])
def remove_comment():
    num_receive = request.form['num_give']
    db.fanbook.delete_one({'num': int(num_receive)})

    return jsonify({'msg': '삭제 완료!'})

@app.route("/homework", methods=["POST"])
def homework_post():
    name_receive = request.form['name_give']
    comment_receive = request.form['comment_give']

    count = time() * 10000000

    doc = {
        'num':count,
        'name':name_receive,
        'comment':comment_receive,
    }
    db.fanbook.insert_one(doc)

    return jsonify({'msg':'기록 완료!'})

@app.route("/homework", methods=["GET"])
def homework_get():
    fanbook_list = list(db.fanbook.find({}, {'_id': False}))
    return jsonify({'fanbooks':fanbook_list})

@app.route("/homework", methods=["PUT"])
def override_comment():
    num_receive = request.form['num_give']
    update_comment_receive = request.form['update_comment']
    update_name_receive = request.form['update_name']
    db.fanbook.update_one({'num':int(num_receive)}, {'$set':{'comment':update_comment_receive}})
    db.fanbook.update_one({'num': int(num_receive)}, {'$set': {'name': update_name_receive}})
    return jsonify({'result':'success', 'msg':'메세지 변경에 성공하였습니다'})

if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)


📄 index.html

    <script>
        function remove_comment(num) {
            $.ajax({
                type: "DELETE",
                url: "/homework/click",
                data: {num_give: num},
                success: function (response) {
                    alert(response["msg"])
                    window.location.reload()
                }
            });
        }

        $(document).ready(function () {
            set_temp()
            show_comment()
        });

        function set_temp() {
            $.ajax({
                type: "GET",
                url: "http://spartacodingclub.shop/sparta_api/weather/seoul",
                data: {},
                success: function (response) {
                    $('#temp').text(response['temp'])
                }
            })
        }

        function save_comment() {
            let name = $('#name').val()
            let comment = $('#comment').val()

            $.ajax({
                type: 'POST',
                url: '/homework',
                data: {name_give:name, comment_give:comment},
                success: function (response) {
                    alert(response['msg'])
                    window.location.reload()
                }
            })
        }

        function show_comment() {
            $.ajax({
                type: "GET",
                url: "/homework",
                data: {},
                success: function (response) {
                    let rows = response['fanbooks']
                    console.log(rows)

                    for(let i=0; i<rows.length; i++){
                        let num = rows[i]['num']
                        let name = rows[i]['name']
                        let comment = rows[i]['comment']

                        let temp_html = `<div id="cards-box" class="card">
                                            <div class="row">
                                                <blockquote class="blockquote mb-0">
                                                    <p>${comment}</p>
                                                    <footer class="blockquote-footer">${name}</footer>
                                                </blockquote>
                                                <div class="col">
                                                    <button onclick="remove_comment(${num})" type="button" class="btn btn-outline-dark">삭제</button>
                                                    <button onclick="show_form(${num})" type="button" class="btn btn-outline-dark">수정</button>
                                                </div>
                                            </div>
                                        </div>

                                    <div id="show-form-${num}" style="display:none;" class="update_mypost">
                                        <div class="form-floating mb-3">
                                            <input type="text" class="form-control" id="update-name-${num}" placeholder="닉네임">
                                            <label for="floatingInput">닉네임</label>
                                        </div>
                                        <div class="form-floating">
                                        <textarea class="form-control" placeholder="Leave a comment here" id="update-comment-${num}"
                                          style="height: 100px"></textarea>
                                            <label for="floatingTextarea2">응원댓글</label>
                                        </div>
                                        <button onclick="override_comment(${num})" type="button" class="btn btn-outline-dark">수정완료</button>
                                    </div>`
                            $('#comment-list').append(temp_html)

                    }
                }
            });
        }

        function show_form(num) {
            let show_id = '#show-form-' + num
            $(`${show_id}`).show();

            $.ajax({
                type: "GET",
                url: "/homework",
                data: {},
                success: function (response) {
                    let rows = response['fanbooks']

                    for (let i = 0; i < rows.length; i++) {
                        let cur_num = rows[i]['num']
                        let cur_name = rows[i]['name']
                        let cur_comment = rows[i]['comment']

                        if(cur_num === num) {
                            name = cur_name
                            comment = cur_comment
                        }
                    }

                    let commentId = '#update-comment-'+ num
                    let nameId = '#update-name-'+ num

                    $(commentId).val(comment)
                    $(nameId).val(name)
                }
            });
        }

        function override_comment(num) {
            let commentId = '#update-comment-'+ num
            let nameId = '#update-name-'+ num
            let comment = $(commentId).val()
            let name = $(nameId).val()


            $.ajax({
                type: "PUT",
                url: "/homework",
                data: {num_give: num, update_comment: comment, update_name: name},
                success: function (response) {
                    alert(response["msg"])
                    window.location.reload()
                }
            });

            let hide_id = '#show-form-' + num
            $(`${hide_id}`).hide();
        }
    </script>

📌 원리

1초(1000) 단위로 끝도 없이 증가하는 time module을 이용해 방명록 데이터의 고유값(html id)을 부여해 삭제, 수정 기능 API 구현.


코드 업로드 : https://github.com/godee95/API-CRUD

 

GitHub - godee95/API-CRUD

Contribute to godee95/API-CRUD development by creating an account on GitHub.

github.com


조원 검색 기능


기존 나의 코드는 frontEnd 부분에 DB서버 데이터를 다 가져와 조원을 검색하는 방법으로 구현했다.
하지만 쿼리 스트링은 frontEnd에서 입력받은 값이 있는 데이터를 찾아 그 해당 데이터만 추출해 조원을 검색가능하도록 즉, backEnd에서 조원 이름과 같은 데이터를 찾도록 구현한 것이다.

📌 쿼리 스트링

웹브라우저는 /yellow/homework 브라우저 url로 서버에 방명록에 기록된 모든 데이터를 요청한다.
서버는 이 요청을 받아 모든 데이터를 json쿼리로 제공해준다.

만약 웹브라우저가 특정 이름 데이터만 찾고 싶으면 /yellow/homework?name=[찾고자하는 이름] url로 서버에 요청하면 된다.

@app.route("/yellow/homework", methods=["GET"])
def homework_get():
    received_name = request.args.get("name")
    if received_name is None:
        visitor_list = list(db.YellowVbook.find({}, {'_id': False}))
    else:
        visitor_list = db.YellowVbook.find_one({"name":received_name},{'_id': False})
    return jsonify({'visitorbooks':visitor_list})

request.args.get("name")으로 서버에서 received_name = [찾고자하는 이름] 값을 받게 된다.

만약, 방명록데이터(YellowVbook)에 [찾고자하는 이름]값이 없으면 방명록에 기록된 모든 데이터를 json쿼리로 제공해준다.

만약, 방명록데이터(YellowVbook)에 [찾고자하는 이름]값이 있으면 방명록에 기록된 데이터 중 name이 [찾고자하는 이름]에 해당하는 데이터만 json쿼리로 제공해준다.



📌 조원분이 고쳐주신 코드!


📄 app.py

@app.route('/searchMember', methods=["GET"])
def serchMember():
    member_name = request.args.get("name_give")
    membersData = db.ProjectMembers.find_one({'name': member_name},{'_id': False})
    print(membersData)

    if membersData is None:
        return jsonify({'msg': 'undefined'})
    else:
        return jsonify({'members_Data' : membersData})

📄 index.html

function search_Member() {
    let inputName = $('#memberName').val()

    let getName
    if (inputName === '') {
        return alert('이름을 입력해주세요')
    } else {
        getName = inputName.trim()
    }

    $.ajax({
        type: "GET",
        url: `/searchMember?name_give=${getName}`,
        data: {},
        success: function (response) {
            let rows = response['members_Data']

            console.log(rows)


            if (rows === undefined) {
                return alert(`${getName}님은 오색조가 아닙니다`)
            } else {
                let name = rows['name']
                let color = rows['color']
                let html = rows['html']

                alert(`${name}님은 오색조의 ${color}멤버 입니다`)
                if(confirm(`${name}님은 ${color}멤버입니다 페이지로 이동 하시겠습니까?`)){
                    location.href = `${html}`
                }
                else {
                    window.location.reload()
                }
            }
        }
    });
}

✏️ 느낀점


캠프 시작하자마자 프로젝트를 시작해서 조금은 힘들었다.
하지만, 짧은 기간안에 많은걸 배운 시간이었다.
웹개발종합반으로 알려주신 걸 실제 프로젝트에서 활용하려고 하니 간단한 것도 오류가 많이 발생했다. 이를 해결하면서 더욱 아는게 많아졌고 성장할 수 있었다.
배운 내용을 다음에도 잘 활용할 수 있도록 내껄로 만들어야 겠다!!