쇼핑몰 주문 DB - syopingmol jumun DB

왁왁s 2021. 6. 7. 06:48

이번 글에서는핑몰에서 클라이언트가 주문한 내용을

데이터베이스에 저장하고, 다시 클라이언트에게 보여주는 것을 해볼 것이다.

그 전에 쇼핑몰에 대한 기본 틀이 있어야 한다.

직접 만들어도 좋지만 예전에 만들어둔 것이 있다.

쇼핑몰 기본 틀 가져오기/ 아래 클릭▼

웹 / 쇼핑몰 기능 추가하기 / Ajax와 jQuery로 쇼핑몰에 환율추가 해보기/ 환율 API 활용한 쇼핑몰

웹 / 쇼핑몰 기능 추가하기 / Ajax와 jQuery로 쇼핑몰에 환율추가 해보기/ 환율 API 활용한 쇼핑몰

이전에 HTML, CSS, JavaScript에 요소들로만 제작하였던 웹 쇼핑몰(?) 비스무리한 것을 다시 한번 더 활용해보고자 한다. HTML, CSS, JavaScript와 함께 이전 글에서 쭉 다뤄왔던 Ajax와 jQuery를 사용해서 쇼핑

parkjh7764.tistory.com

쇼핑몰 주문 DB - syopingmol jumun DB

해당 쇼핑몰에 대한 기본 틀은 위 링크를 통해 가져온 코드를 나타내겠다.

맨 아래 코드를 index.html 파일에 복사 붙여넣기 하고 

크롬을 통해 열어보면 아래와 같은 단순한 쇼핑몰 형태의 웹이 나타날 것이다.

쇼핑몰 주문 DB - syopingmol jumun DB

쇼핑몰 기본 골격 HTML 코드

이전에 만들어 놓은 환율 적용한 웹 쇼핑몰 html 골격 코드
<!doctype html>
<html lang="en">

<head>
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Do+Hyeon&display=swap" rel="stylesheet">   
    <!-- 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">

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap 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>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
        integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
        crossorigin="anonymous"></script>

    <style>
        *{
            font-family: 'Do Hyeon', sans-serif;
        }
        .item_img{
            width: 800px;
            height: 500px;
            margin: auto;
            margin-top: 20px;
            margin-bottom: 50px;
        }
        .item_size{
            width: 800px;
            height: 500px;
        }
        .item_price{
            font-size: 20px;
            opacity: 0.7;
        }
        .price_rate{
            font-size : 21px;
            color: red;
            opacity: 0.7;
        }
        .blue_color{
            color: royalblue;
        }
        .order_button{
            width: 20px;
            display: block;
            margin: auto;
            
        }
        .order_menu{
            width: 700px;
            margin: 40px auto;

        }

        .main_menu{
            width: 800px;
            margin: auto;
            
        }
        .main_menu_margin{
            text-align: center;
        }
        
    </style>

    <script>
        function order(){
            alert("주문이 완료되었습니다.");
        }
    </script>

    <script>
        $(document).ready(function(){
                $.ajax({
                type: "GET",
                url: "https://api.manana.kr/exchange/rate.json",
                data: {},
                success: function(response){
                    let change_rt = response[1]["rate"]
                    let item_dollar = Math.ceil(1900000 / change_rt) 
                    $("#exchange_rate").append(`${change_rt}원`)
                    $("#exchange_rate").append(`<span class="blue_color"> ▶환율 계산한 맥북 가격 : ${item_dollar}달러</span>`)
                    }
                });
        });

    </script>
    <title>쇼핑몰</title>
</head>

<body>
    <!-- 상품 상단 이미지 -->
    <div class="item_img">
    <div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
        <ol class="carousel-indicators">
          <li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
          <li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
          <li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
        </ol>
        <div class="carousel-inner">
          <div class="carousel-item active">
            <img class="item_size" class="d-block w-100" src="https://img1.daumcdn.net/thumb/R800x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F990C1D3A5B65974F07" alt="First slide">
          </div>
          <div class="carousel-item">
            <img class="item_size" class="d-block w-100" src="https://t1.daumcdn.net/cfile/tistory/992792445EB0253129" alt="Second slide">
          </div>
          <div class="carousel-item">
            <img class="item_size" class="d-block w-100" src="https://images.kbench.com/kbench/article/2020_11/k216197p1n1.jpg" alt="Third slide">
          </div>
        </div>
        <a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
          <span class="carousel-control-prev-icon" aria-hidden="true"></span>
          <span class="sr-only">Previous</span>
        </a>
        <a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
          <span class="carousel-control-next-icon" aria-hidden="true"></span>
          <span class="sr-only">Next</span>
        </a>
      </div>
    </div>
    
        <div class="main_menu">
            <h2> 맥북 프로(MacBook PRO) <span class="item_price">가격: 1,900,000원 / 1개</span> </h2>
            <span class="price_rate" id="exchange_rate">환율 1$↔</span> 
            <div class="main_menu_margin">이 상품으로 말할 것 같으면 애플(Apple)사에서 출시한 매우 세련된 디자인으로 감성까지 지녔으며 심지어 성능도 좋은
                노트북입니다. 가격만 보면 비싸다고 느껴지실텐데, 직접 사용해보신다면 가격이 절대 비싸지 않다고 장담할 수 있습니다.
        </div> 
        

        <form class="order_menu">
            <h2> Order</h2>    
        

          <!-- 주문/주문자 이름 -->
          <div class="input-group mb-3">
            <div class="input-group-prepend">
              <span class="input-group-text" id="basic-addon1">주문자 이름</span>
            </div>
            <input type="text" class="form-control" placeholder="Username" aria-label="User name" aria-describedby="basic-addon1">
          </div>

          
          <!-- 주문/수량 -->
          <div class="input-group mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="inputGroupSelect01">수량</label>
            </div>
            <select class="custom-select" id="inputGroupSelect01">
              <option selected>Choose a quantity </option>
              <option value="1">1</option>
              <option value="2">2</option>
              <option value="3">3</option>
              <option value="4">4</option>
              <option value="5">5</option>
              <option value="6">6</option>
              <option value="7">7</option>
              <option value="8">8</option>
              <option value="9">9</option>
            </select>
          </div>

          <!-- 주문/주소 -->
          <div class="input-group mb-3">
            <div class="input-group-prepend">
              <span class="input-group-text" id="basic-addon1">주소</span>
            </div>
            <input type="text" class="form-control" placeholder="Address" aria-label="Username" aria-describedby="basic-addon1">
          </div>
          <!-- 주문/전화번호 -->
          <div class="input-group mb-3">
            <div class="input-group-prepend">
              <span class="input-group-text" id="basic-addon1">전화번호</span>
            </div>
            <input type="text" class="form-control" placeholder="Telephone" aria-label="Username" aria-describedby="basic-addon1">
          </div>
          <!-- 주문/제출버튼 -->
            <div class="order_button">
                 <button type="submit" onclick="order()" class="btn btn-primary">주문하기</button>
            </div>
        </form>
    </div>
</body>

</html>


그럼 이전 글에서부터 다뤄왔던 데이터베이스(DB)와 서버를 쇼핑몰에도 적용해보겠다.

그전에 프로젝트 세팅을 해주자.

프로젝트 세팅하기

shoppingmal 이라는 새 프로젝트를 생성하고

static 폴더, templates 폴더, index.html 파일, app.py 파일을 생성해준다.

쇼핑몰 주문 DB - syopingmol jumun DB

그리고 app.py 파일에는 서버를 구동하고, API를 제공하기 위한 

코드를 작성해야 한다.

기본 틀은 제공하겠다. 기본 틀을 복사 붙여넣기 해주고

필요한 부분을 고쳐서 작성하면 된다.

app.py 파일 / 서버 구동, API 제공하기 위한 기본 골격 코드
from flask import Flask, render_template, jsonify, request

app = Flask(__name__)

from pymongo import MongoClient

client = MongoClient('localhost', 27017)
db = client.dbshop


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


# 주문하기(POST) API
@app.route('/order', methods=['POST'])
def save_order():
    sample_receive = request.form['sample_give']
    print(sample_receive)
    return jsonify({'msg': '이 요청은 POST!'})


# 주문 목록보기(Read) API
@app.route('/order', methods=['GET'])
def view_orders():
    sample_receive = request.args.get('sample_give')
    print(sample_receive)
    return jsonify({'msg': '이 요청은 GET!'})


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

API 설계하기

우선 API를 

클라이언트가 사고싶은 상품을 주문하는 것(POST 방식)

주문한 내역을 보는 것(GET 방식)으로 나눌 수 있다.

POST 방식

그러면 우리가 클라이언트로부터 받아야할 것

Order 부분으로,

주문자의 이름, 주문수량, 주소, 전화번호를 받아야 한다.

그리고 받은 데이터를 데이터베이스(DB)에 저장해준다. 

GET 방식

주문한 내역을 페이지를 로딩할 때 하단에 보이도록 한다.

이때 데이터베이스(DB)에 저장된 주문자의 정보를 가지고 온 후에

양식에 맞게 웹에 업로드 해줘야 한다.


클라이언트로부터 주문 정보 받아서 데이터베이스에 저장하기 (POST 방식)

서버에서는 어떤 코드를 작성해줘야 할까?

서버에서는 클라이언트가 입력한

주문자의 이름, 주문수량, 주소, 전화번호를 받아와서

데이터베이스에 저장해주는 코드를 작성하면 되는 것이다.


POST 방식이기 때문에 request.args.get(' ')가 아닌, request.form[' '] 형태로 데이터 전송을 해야 한다.

4가지 변수를 선언해 4개의 데이터를 받아오고,

딕셔너리 형태로 구성해 'shoppingmal'이라는 DB 컬렉션에 삽입해준다.

app.py 파일 / 주문하기 (POST) API 코드
# 주문하기(POST) API
@app.route('/order', methods=['POST'])
def save_order():
    name_receive = request.form['name_give']
    quantity_receive = request.form['quantity_give']
    address_receive = request.form['address_give']
    phone_receive = request.form['phone_give']

    db_input = {
        'name' : name_receive,
        'quantity' : quantity_receive,
        'address' : address_receive,
        'phone' : phone_receive
    }
    db.shoppingmal.insert_one(db_input)
    return jsonify({'msg': '주문이 완료되었습니다.'})

그러면 클라이언트 부분에서는?

제이쿼리를 사용해

사용자가 입력한 데이터 값을 .val( )로 받아와 변수에 넣는다.

ajax키(key) : 값(value)의 형태로 서버에 넘긴다.

그리고 해당 order( ) 함수는 [주문하기] 버튼이 눌렀을 때 실행이 된다.

window.location.reload( ); 를 작성하여 주문하기 버튼을 눌렀을 때

새로고침이 되는 기능을 추가한다.

index.html 파일 / 주문하기 버튼을 눌렀을 때 실행되는 함수 코드 (POST 방식)
        function order() {
                let name = $("#input-name").val();
                let quantity = $("#input-quantity").val();
                let address = $("#input-address").val();
                let phone = $("#input-phone").val();


                $.ajax({
                    type: "POST",
                    url: "/order",
                    data: {name_give:name, quantity_give:quantity, address_give:address, phone_give:phone },
                    success: function (response) {
                            alert(response["msg"]);
                            window.location.reload();
                    }
                })
            }


데이터베이스(DB)에 저장된 주문 정보를 불러와 리스팅하기 (GET 방식)

서버 파일(app.py)부터 살펴보자.

서버에서 해줄 일은 데이터베이스(DB)에 저장된 클라이언트의 주문정보를 찾아서

ajax에서 활용할 수 있도록 키(key) 값으로 제공해주는 것이다.

app.py 파일 / 데이터베이스(DB)에 저장된 주문정보 가져오기
# 주문 목록보기(Read) API
@app.route('/order', methods=['GET'])
def view_orders():
    orders = list(db.shoppingmal.find({}, {'_id':False}))
    return jsonify({'all_orders': orders})

클라이언트(index.html) 부분을 살펴보자.

여기도 어렵지 않다. 

서버에서 보내준 데이터를 'all_orders'라는 키(key) 값으로 받아서

우리가 원하는 정보를 분류하기 위해 for 반복문을 돌린다.

주문자 이름(name), 주문수량(quantity), 주소(address), 전화번호(phone)

변수를 두어 데이터를 분류시킨다.

그리고 ` ` (백틱)을 활용해 [표] 형태로 만들어 주면 끝이다.

표 형태의 html 코드를 제이쿼리 .append 함수를 통해 해당 부분에 붙여넣기 해주면 된다 !

            function showOrder() {
                $.ajax({
                    type: "GET",
                    url: "/order",
                    data: {},
                    success: function (response) {
                            let client_order = response['all_orders'];
                            for(let i = 0; i < client_order.length; i++){
                                let name = client_order[i]['name'];
                                let quantity = client_order[i]['quantity'];
                                let address = client_order[i]['address'];
                                let phone = client_order[i]['phone'];
                                let temp_html = `<tr>
                                                    <td></td>
                                                    <td>${name}</td>
                                                    <td>${quantity}</td>
                                                    <td>${address}</td>
                                                    <td>${phone}</td>>
                                                </tr>`
                                $("#client_ordermenu").append(temp_html)
                            }
                    }
                })
            }

정상 작동되는지 확인하기


자 그러면 정상적으로 작동이 되는지 살펴보자.

localhost:5000으로 서버에 접속하면 아래와 같은 화면이 나온다.

사용자가 주문한 목록을 볼 수 있도록 Client Order 부분을 추가해놨다.

이는 맨 아래에 완성된 코드로 남겨놓을테니 필요하면 복사하자.

쇼핑몰 주문 DB - syopingmol jumun DB

자 그러면 주문을 해보자.

이름과 수량, 주소, 전화번호를 입력한 후에

[주문하기] 버튼을 눌러보자.

쇼핑몰 주문 DB - syopingmol jumun DB

그러면 '주문이 완료되었습니다.'라는 알림창(alert)이 뜬다.

쇼핑몰 주문 DB - syopingmol jumun DB

Client Order 부분에 내가 입력한 주문 정보가

추가된 것을 확인할 수 있다. wow!!!

쇼핑몰 주문 DB - syopingmol jumun DB

자 그러면 신나게 주문을 해보자.

김부자는 부자여서 그런지 맥북 프로 노트북을 9개나 주문했다.

쇼핑몰 주문 DB - syopingmol jumun DB

그러면 주문 정보에 대한 데이터를 관리하고 있는 데이터베이스도 확인해보자.

Robo 3T를 통해  mongoDB를 확인해보면 4명의 주문자 정보가 저장된 것을 확인할 수 있다.

쇼핑몰 주문 DB - syopingmol jumun DB