본문 바로가기
스파르타/웹개발

22.02.04 POST & GET 연습 <모두의 책리뷰> / PyCharm에 JQuery 최신버전 설치하기

by h.단디 2022. 2. 6.

POST

[API만들고 사용하는 순서] 

1. 클라이언트와 서버 확인하기

서버코드

## API 역할을 하는 부분
@app.route('/review', methods=['POST'])
def write_review():
    sample_receive = request.form['sample_give']         #서버에 title, author, review 가져와야함
    print(sample_receive)                                #서버는 DB에 정보 insert해야함
    return jsonify({'msg': '이 요청은 POST!'})            #성공여부 & 성공메시지 반환

클라이언트 코드

function makeReview() {
                $.ajax({
                    type: "POST",
                    url: "/review",
                    data: {sample_give:'샘플데이터'},      // 제목, 저자, 리뷰 내용을 가져와야함
                    success: function (response) {         // 그중 하나라도 입력 안 하면 alert 띄우기
                        alert(response["msg"]);            // /review에 POST로 저장요청하기
                        window.location.reload();          // 저장하면 새로고침되게 하는 코드
                    }
                })
            }

▶ 동작 테스트 : '리뷰 시작하기' 버튼 눌렀을 때, '저장 완료'라는 alert창이 뜨면 클라이언트 코드&서버코드 연결 됐다는 뜻

 

 

2. 서버부터 만들기 - 클라이언트에게 보낸 요청 데이터를 데이터베이스에 생성(Create)하고, 저장이 성공했다고 응답 데이터를 보냄

@app.route('/review', methods=['POST'])
def write_review():
    title_receive = request.form['title_give']          # 클라이언트에게 요청할 데이터 : title/author/review
    author_receive = request.form['author_give']        # 클라이언트가 준 title/author/review를 ~_receive로 가져옴
    review_receive = request.form['review_give']

    doc = {                                             # DB에 insert할 review만들기
        'title': title_receive,
        'author': author_receive,
        'review': review_receive
    }
    db.bookreview.insert_one(doc)                       # bookreview라는 서버에 review 저장하기

    return jsonify({'msg': '리뷰가 성공적으로 작성되었습니다.'})    #성공여부 & 성공메시지 반환

3. 클라이언트 만들기

function makeReview() {
    let title = $("#title").val();                 // input에서 제목, 저자, 리뷰내용 가져옴
    let author = $("#author").val();
    let review = $("#bookReview").val();

    $.ajax({
        type: "POST",                              // /review에 POST (저장 creat)요청
        url: "/review",
        data: { title_give: title, author_give: author, review_give: review },
        success: function (response) {
            alert(response["msg"]);               // 성공하면 서버에서 클라이언트에게 '저장완료'라는 응답 데이터 보냄
            window.location.reload();             // 화면 다시 로딩
        }
    })
}

 

4. 완성 확인하기

제목, 저자, 리뷰 작성 후 '리뷰 작성하기' 버튼 눌렀을 때 '저장 완료!'라는 alert가 뜨면 된거임.

 

 

 

GET

[API만들고 사용하는 순서] 

1. 클라이언트와 서버 확인하기

서버코드

@app.route('/review', methods=['GET'])
def read_reviews():
    sample_receive = request.args.get('sample_give')
    print(sample_receive)
    return jsonify({'msg': '이 요청은 GET!'})

클라이언트 코드

function showReview() {
		$.ajax({                                 
        type: "GET",                                //서버 데이터 받아올게
        url: "/review?sample_give=샘플데이터",
        data: {},
        success: function (response) {
            alert(response["msg"]);
        }
    })
}

▶ 동작 테스트 : 새로고침 했을 때 '리뷰를 받아왔습니다.'라는 내용의 alert 뜨면 클라이언트&서버 코드 연결 되어있다는 뜻.

 

 

2. 서버부터 만들기 - 데이터베이스에 리뷰 정보를 조회(Read)하고, 성공 메시지와 리뷰 정보를 응답 데이터를 보냄

@app.route('/review', methods=['GET'])
def read_reviews():                                             #서버가 클라이언트에게 요청할 데이터는 없음
    reviews = list(db.bookreview.find({}, {'_id': False}))      # 걍 DB에 있는 리뷰 정보를 몽땅({}) 가져오면 됨 
    return jsonify({'all_reviews': reviews})                    # 성공 여부 & reviews라는 리뷰리스트로 반환하기

3. 클라이언트 만들기

function showReview() {
                $.ajax({
                    type: "GET",
                    url: "/review",
                    data: {},
                    success: function (response) {
                        let reviews = response['all_reviews']             //서버로부터 받은 all_reviews를 reviews라는 리스트로 받을게
                        for (let i = 0; i < reviews.length; i++) {        //리스트를 반복문으로 돌릴건데 말이야
                            let title = reviews[i]['title']               //리스트 i번째 title/author/review은 각각 title/author/review로 받을게
                            let author = reviews[i]['author'] 
                            let review = reviews[i]['review']           

                            let temp_html = `<tr>                          // 모든 title/author/review를 tr로 묶어서 temp_html로 만든 다음에
                                                <td>${title}</td>
                                                <td>${author}</td>
                                                <td>${review}</td>
                                            </tr>`
                            $('#reviews-box').append(temp_html)            // 그 temp_html을 reviews에 붙여넣을게
                        }
                    }
                })
            }

4. 완성 확인하기

새로고침 했을 때 DB에 저장된 리뷰가 화면에 붙으면 정상 작동한거임.

 

 

 

완성코드

서버 코드

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

from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta

## HTML을 주는 부분
@app.route('/')
def home():
    return render_template('index.html')

## API 역할을 하는 부분
@app.route('/review', methods=['POST'])
def write_review():
    title_receive = request.form['title_give']
    author_receive = request.form['author_give']
    review_receive = request.form['review_give']

    doc = {
        'title':title_receive,
        'author':author_receive,
        'review':review_receive
    }

    db.bookreview.insert_one(doc)

    return jsonify({'msg': '저장 완료!'})       


@app.route('/review', methods=['GET'])
def read_reviews():
    reviews = list(db.bookreview.find({}, {'_id': False}))
    return jsonify({'all_reviews': reviews})            


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

클라이언트 코드

<!DOCTYPE html>
<html lang="ko">

    <head>
        <!-- Webpage Title -->
        <title>모두의 책리뷰 | 스파르타코딩클럽</title>

        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
              integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
              crossorigin="anonymous">

        <!-- JS -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
                integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
                crossorigin="anonymous"></script>

        <!-- 구글폰트 -->
        <link href="https://fonts.googleapis.com/css?family=Do+Hyeon&display=swap" rel="stylesheet">

        <script type="text/javascript">

            $(document).ready(function () {
                showReview();
            });

            function makeReview() {
                let title = $('#title').val()
                let author = $('#author').val()
                let review = $('#bookReview').val()

                $.ajax({
                    type: "POST",
                    url: "/review",
                    data: {title_give:title,author_give:author,review_give:review},
                    success: function (response) {
                        alert(response["msg"]);
                        window.location.reload();
                    }
                })
            }

            function showReview() {
                $.ajax({
                    type: "GET",
                    url: "/review",
                    data: {},
                    success: function (response) {
                        let reviews = response['all_reviews']
                        for (let i = 0; i < reviews.length; i++) {
                            let title = reviews[i]['title']
                            let author = reviews[i]['author']
                            let review = reviews[i]['review']

                            let temp_html = `<tr>
                                                <td>${title}</td>
                                                <td>${author}</td>
                                                <td>${review}</td>
                                            </tr>`
                            $('#reviews-box').append(temp_html)
                        }
                    }
                })
            }

        </script>


        <style type="text/css">
            * {
                font-family: "Do Hyeon", sans-serif;
            }

            h1,
            h5 {
                display: inline;
            }

            .info {
                margin-top: 20px;
                margin-bottom: 20px;
            }

            .review {
                text-align: center;
            }

            .reviews {
                margin-top: 100px;
            }
        </style>
    </head>

    <body>
        <div class="container" style="max-width: 600px;">
            <img src="https://image.freepik.com/free-vector/large-bookcase-with-books-library-book-shelf-interior_92863-357.jpg"
                 class="img-fluid" alt="Responsive image">
            <div class="info">
                <h1>읽은 책에 대해 말씀해주세요.</h1>
                <p>다른 사람을 위해 리뷰를 남겨주세요! 다 같이 좋은 책을 읽는다면 다 함께 행복해질 수 있지 않을까요?</p>
                <div class="input-group mb-3">
                    <div class="input-group-prepend">
                        <span class="input-group-text">제목</span>
                    </div>
                    <input type="text" class="form-control" id="title">
                </div>
                <div class="input-group mb-3">
                    <div class="input-group-prepend">
                        <span class="input-group-text">저자</span>
                    </div>
                    <input type="text" class="form-control" id="author">
                </div>
                <div class="input-group mb-3">
                    <div class="input-group-prepend">
                        <span class="input-group-text">리뷰</span>
                    </div>
                    <textarea class="form-control" id="bookReview"
                              cols="30"
                              rows="5" placeholder="140자까지 입력할 수 있습니다."></textarea>
                </div>
                <div class="review">
                    <button onclick="makeReview()" type="button" class="btn btn-primary">리뷰 작성하기</button>
                </div>
            </div>
            <div class="reviews">
                <table class="table">
                    <thead>
                    <tr>
                        <th scope="col">제목</th>
                        <th scope="col">저자</th>
                        <th scope="col">리뷰</th>
                    </tr>
                    </thead>
                    <tbody id="reviews-box">
                    </tbody>
                </table>
            </div>
        </div>
    </body>

</html>

 

 

 

JQuery 최신버전 설치하기

 POST에서 클라이언트 코드를 짤 때

data: { title_give: title, author_give: author, review_give: review }

를 작성했는데 key들이 제대로 활성화되지 않았다. 몇번이나 다 지우고 강의 들이면서 다시 처음으로 돌아가서 따라해봐도 마찬가지였다. 슬랙에 검색해봐도 명확한 답변은 없고... 4번쯤 반복하는 동안 계속 저 코드 한줄에만 얽매이다가 문득 바로 그 윗줄에 .val() 이 작동하지 않는 걸 깨달았다. .val()로 값을 가져오는데 실패했으니 당연히 key로 안 먹히지 ㅠ .val()에 마우스를 가져가보니 'unsolved function~~'이라고 알림이 뜨길래 구글링해보니 jquery 최신버전으로 설치하면 간단히 해결되는 문제였다...!!!! 내가 이거때문에 머리싸매고 있던 시간이 아까웠지만 그래도 해답을 찾았으니 다행..

 

 

그래서 설치하는 방법은 ?

JQuery 공식홈페이지에서 최신버전으로 다운받은 뒤 

PyCharm(window의 경우 File >Setting) > Preferences > Language&Frameworks > Javascript > Libraries > ADD > + > Attache files > 다운받은 JQuery.js 파일 추가 후 OK.

 

 

 

 

진짜 안 될 때 너무 짜증나서 눈물나려고 했었는데 허무하게 해결됨 ...ㅎ ;