[스파르타코딩클럽] 웹개발 종합반 4주차

웹개발 종합반 4주차

📝배운것

  • Flask 프레임워크 사용 및 숙달
  • 클라이언트 서버 연동 반복 연습

클라이언트 - 서버 연결 전체 그림

Flask

  • 패키지 설치
    flask package 설치

Flask 기초

서버를 구동시켜주는 편한 코드 모음. 서버를 구동하려면 필요한 복잡한 일들을 쉽게 가져다 쓸 수 있습니다.

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

실행

  • URL 나누기
from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
   return 'This is Home!'

@app.route('/mypage')
def mypage():  
   return 'This is My Page!'

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

기본 폴더 구조

👉 Flask 서버를 만들 때, 항상,

프로젝트 폴더 안에,
ㄴstatic 폴더 (이미지, css파일을 넣어둡니다)
ㄴtemplates 폴더 (html파일을 넣어둡니다)
ㄴapp.py 파일

이렇게 세 개를 만들어두고 시작하세요. 이제 각 폴더의 역할을 알아봅시다!

(꼭 참고!! venv는 실제로는 보이지만, 안보인다~라고 생각하세요! 기억하시죠?)

  • templates 폴더에 index.html 파일 생성
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <title>Document</title>
</head>
<body>
    <h1>서버를 만들었다!</h1>
</body>
</html>
  • flask 내장함수 render_remplate 임포트하여 html파일 불러오기
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 만들기

👉 **GET, POST 방식**

여러 방식(링크)이 존재하지만 우리는 가장 많이 쓰이는 GET, POST 방식에 대해 다루겠습니다.


  • GET → 통상적으로! 데이터 조회(Read)를 요청할 때
    예) 영화 목록 조회
    데이터 전달 : URL 뒤에 물음표를 붙여 key=value로 전달
    → 예: google.com?q=북극곰

  • POST → 통상적으로! 데이터 생성(Create), 변경(Update), 삭제(Delete) 요청 할 때
    예) 회원가입, 회원탈퇴, 비밀번호 수정
    데이터 전달 : 바로 보이지 않는 HTML body에 key:value 형태로 전달


연습1 - 모두의책리뷰

  • 서버 (app.py)
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():

    # 클라이언트에서 보낸 data 가져오기
    title_receive = request.form['title_give']
    author_receive = request.form['author_give']
    review_receive = request.form['review_give']

    # DB 에 넣어줄 dic 만들어주기
    dic = {
        'title': title_receive,
        'author': author_receive,
        'review': review_receive
    }

    # DB 에 Insert
    db.bookreview.insert_one(dic)

    return jsonify({'msg': '저장되었습니다.', 'result':'success'})


@app.route('/review', methods=['GET'])
def read_reviews():

    # DB 에서 북리뷰 리스트 가져오기
    book_list = list(db.bookreview.find({}, {'_id':False}))

    return jsonify({'result': 'success', 'all_books': book_list})

if __name__ == '__main__':
    app.run('0.0.0.0', port=5001, debug=True)
  • 클라이언트 (index.html)
<script type="text/javascript">

            $(document).ready(function () {
                $('#reviews-box').empty();
                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) {
                        if (response['result'] === 'success') {
                            alert(response['msg'])
                            location.reload();
                        }
                    }
                })
            }

            function showReview() {
                $.ajax({
                    type: "GET",
                    url: "/review",
                    data: {},
                    success: function (response) {
                        if (response['result'] === 'success') {
                            let all_books = response['all_books']

                            for (let i = 0; i < all_books.length; i++) {
                                let book = all_books[i];

                                let title = book['title'];
                                let author = book['author'];
                                let review = book['review'];

                                let temp_html = `<tr>
                                                    <td>${title}</td>
                                                    <td>${author}</td>
                                                    <td>${review}</td>
                                                </tr>`;

                                $('#reviews-box').append(temp_html);
                            }
                        }
                    }
                })
            }
        </script>

연습2 - 나홀로메모장

  • 서버 (app.py)
from flask import Flask, render_template, jsonify, request
app = Flask(__name__)

import requests
from bs4 import BeautifulSoup

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

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

@app.route('/memo', methods=['GET'])
def listing():

    # DB에 저장되어있는 데이터 가져오기
    articles = list(db.articles.find({},{'_id':False}))

    return jsonify({'result':'success', 'all_articles': articles})


## API 역할을 하는 부분
@app.route('/memo', methods=['POST'])
def saving():
    url_receive = request.form['url_give']
    comment_receive = request.form['comment_give']

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get(url_receive, headers=headers)

    soup = BeautifulSoup(data.text, 'html.parser')

    # 여기에 코딩을 해서 meta tag를 먼저 가져와보겠습니다.

    image = soup.select_one('meta[property="og:image"]')['content']
    title = soup.select_one('meta[property="og:title"]')['content']
    description = soup.select_one('meta[property="og:description"]')['content']

    dic = {
        'title': title,
        'description': description,
        'url': url_receive,
        'image_url': image,
        'comment': comment_receive
    }

    db.articles.insert_one(dic)

    return jsonify({'msg': '저장완료', 'result': 'success'})


if __name__ == '__main__':
   app.run('0.0.0.0',port=5001,debug=True)
  • 클라이언트 (index.html)
<script>
            $(document).ready(function () {
                $('#cards-box').empty();
                showArticles();
            });
            
            function openClose() {
                if ($("#post-box").css("display") == "block") {
                    $("#post-box").hide();
                    $("#btn-post-box").text("포스팅 박스 열기");
                } else {
                    $("#post-box").show();
                    $("#btn-post-box").text("포스팅 박스 닫기");
                }
            }

            function postArticle() {

                let post_url = $('#post-url').val();
                let comment = $('#post-comment').val();

                $.ajax({
                    type: "POST",
                    url: "/memo",
                    data: {url_give:post_url, comment_give:comment},
                    success: function (response) { // 성공하면
                        if (response['result'] === 'success') {
                            alert(response['msg']);
                            location.reload();
                        }
                    }
                })
            }

            function showArticles() {
                $.ajax({
                    type: "GET",
                    url: "/memo",
                    data: {},
                    success: function (response) {
                        if (response['result'] === 'success') {
                            let articles = response['all_articles'];

                            for (let i = 0; i < articles.length; i++) {
                                let article = articles[i];

                                let title = article['title'];
                                let comment = article['comment'];
                                let desc = article['description'];
                                let url = article['url'];
                                let image = article['image_url'];

                                let temp_html = `<div class="card">
                                                    <img class="card-img-top"
                                                         src="${image}"
                                                         alt="Card image cap">
                                                    <div class="card-body">
                                                        <a target="_blank" href="${url}" class="card-title">${title}</a>
                                                        <p class="card-text">${desc}</p>
                                                        <p class="card-text comment">${comment}</p>
                                                    </div>
                                                </div>`;

                                $('#cards-box').append(temp_html);
                            }
                        }
                    }
                })
            }
        </script>

연습3 - 쇼핑몰 주문, 내역 조회

-서버 (app.py)

from flask import Flask, render_template, jsonify, request

app = Flask(__name__)

from pymongo import MongoClient

# client = MongoClient('localhost', 27017)
client = MongoClient('mongodb://test:test@localhost', 27017)
db = client.dbhomework

## HTML 화면 보여주기
@app.route('/')
def homework():
    return render_template('index.html')

# 주문하기(POST) API
@app.route('/order', methods=['POST'])
def save_order():
    name_receive = request.form['name_give']
    count_receive = request.form['count_give']
    addr_receive = request.form['addr_give']
    phone_receive = request.form['phone_give']

    print(name_receive, count_receive, addr_receive, phone_receive)

    # DB에 저장
    # 1. dic 만들기
    dic = {
        'name': name_receive,
        'count': count_receive,
        'addr': addr_receive,
        'phone': phone_receive
    }

    # 2. 저장
    db.order.insert_one(dic)

    return jsonify({'result':'success', 'msg': '기사가 저장되었습니다.'})


# 주문 목록보기(Read) API
@app.route('/order', methods=['GET'])
def view_orders():

    # db 에서 리스트 가져기
    orders = list(db.order.find({},{'_id':False}))

    return jsonify({'result':'success', 'orders': orders})

if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)
  • 클라이언트 (index.html)
<script>

        $(document).ready(function () {
            $.ajax({
                type: "GET",
                url: "https://api.manana.kr/exchange/rate.json",
                data: {},
                success: function (response) {
                    let nowRate = response[1]['rate'];
                    $('#rate-box').text(nowRate);
                }
            })
            $('#orders-box').empty();
            order_listing();
        });

        function order_listing() {
            // 주문목록 보기 API 연결
						$.ajax({
                type: "GET",
                url: "/order",
                data: {},
                success: function (response) {
                    if (response['result'] === 'success') {
                        let orders = response['orders'];

                        for (let i = 0; i < orders.length; i++) {
                            let order = orders[i];
                            let name = order['name'];
                            let count = order['count'];
                            let addr = order['addr'];
                            let phone = order['phone'];

                            let temp_html = `<tr>
                                          <th scope="row">${name}</th>
                                          <td>${count}</td>
                                          <td>${addr}</td>
                                          <td>${phone}</td>
                                        </tr>`;

                            $('#orders-box').append(temp_html);
                        }
                    }
                }
            })
        }

        function order() {
            // 값 가져오기
            let name = $('#order-name').val();
            let count = $('#order-count').val();
            let addr = $('#order-address').val();
            let phone = $('#order-phone').val();

            // 주문하기 API 연결
						$.ajax({
                type: "POST",
                url: "/order",
                data: {'name_give':name, 'count_give':count, 'addr_give':addr, 'phone_give':phone},
                success: function (response) { // 성공하면
                    if (response['result'] === 'success') {
                        alert(response["msg"]);
                        location.reload();
                    }
                }
            })
        }
    </script>

좋은 웹페이지 즐겨찾기