<4주차> Flask 를 이용한 서버 구축

팽팽 2021. 8. 28. 14:58

Flask란?

파이썬으로 작성된 프레임 워크로써 서버를 구동시켜주는 편한 코드 모음.

서버를 구동하려면 필요한 복잡한 일들을 쉽게 가져다 쓸 수 있음

flask서버를 만들때는 프로젝트 폴더안에

static - 이미지, css

templates - html 파일을 담아오고 불러옴

app.py

폴더를 만들고 시작해야한다.

다음은 flask 시작코드이다. app.py에 작성한다.

from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'This is Home!'
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)

HTML 파일을 불러올때는 flask의 내장함수인 render_template를 이용한다.

from flask import Flask, render_template
app = Flask(__name__)
## URL 별로 함수명이 같거나,
## route('/') 등의 주소가 같으면 안됩니다.
@app.route('/')
def home():
return render_template('index.html')
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)

API를 만들어보자

클라이언트가 요청 할 때, 방식이 존재함

http라는 통신 규약을 따르는데 클라이언트는 요청할 때 HTTP라는 요청 메소드를 통해 

어떤 요청 종류인지 응답하는 서버쪽에 정보를 알려줌

그 종류에는 2가지가 있음!

1. GET

2. POST

GET방식은 데이터를 조회(READ)할때 이용하는 방식으로 URL뒤에 ?(쿼리스트링)을 붙여

key= value 값으로 전달함

POST방식은 데이터를 생성,변경,삭제할때 사용하고 보이지 않는 HTML BODY에 KEY =VALUE 값으로 전달한다.

<모두의 책 리뷰 예시>

1. POST

제목, 저자 , 리뷰 정보 저장하기

서버코드 - app.py

-client가 준 title, author, review 가져오기

-db에 삽입하기

-성공여부, 성공메세지 반환

## 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({'result': 'success', 'msg': '리뷰가 성공적으로 작성되었습니다.'})

 

클라이언트 코드 - index.html

-제목, 저자, 리뷰 내용을 가져옵니다.

-제목, 저자, 리뷰 중 하나라도 입력하지 않았을 경우 alert를 띄웁니다.

- POST /review 에 저장을 요청합니다.

 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();
                    }
                })
            }

2. GET

저장된 리뷰 화면에 보여주기

서버코드 - app.py

 

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

클라이언트 코드 - index.html

 

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)
                        }
                    }
                })
            }

app.js

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)

index.js

<!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">
            <img src="https://previews.123rf.com/images/maxxyustas/maxxyustas1511/maxxyustas151100002/47858355-education-concept-books-and-textbooks-on-the-bookshelf-3d.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>>