[スパルタコードクラブ]ネットワーク開発総合クラス-4週間(2)
110997 ワード
2週目のタスクでのオーダー履歴の呼び出し
コード#コード#
index.html app.py
@app.route('/order', methods=['POST']) サーバのPOSTが/orderを受信しているため、クライアントの機能もurlで/orderを受信します.
接続の確認 app.py
return jsonify({'result': 'success', 'msg': 'Thank you for your order!'}) 「Buy Now」ボタンをクリックすると、次のalertウィンドウが表示されます.
DB insert
app.py
[スパルタコードクラブ]ネットワーク開発総合クラス-第3週(3)を参照してください.
➊input値の指定 body script
この場合、「Option」の値はinputではなくcustom-selectであるため、idはcustom-selectに付与される.
入力値の送信 app.py index.html
dateは、サーバが受信を決定する名前と一致する必要があります.
を送信するかどうかは、Robo 3 Tを参照してください.
➊クライアント位置決定
➋ ajax
接続の確認
クライアント要求を受信したサーバ呼び出しメッセージ.
が正常に呼び出されるとalertウィンドウが停止します
「ordersは変数にすぎません.」重要なのはall ordersを降ろすことです.
ドア.
❷ orders table HTML CSS
❸ temp_html body script
既存の値をfor文の変数に変更
Orders-boxでappend(temp html)に送信
予期せぬ待ち伏せCSS
コード#コード#
app.py
from flask import Flask, render_template, jsonify, request
app = Flask(__name__)
from pymongo import MongoClient
client = MongoClient('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']
phone_receive = request.form['phone_give']
address_receive = request.form['address_give']
options_receive = request.form['options_give']
doc = {
'name':name_receive,
'phone':phone_receive,
'address':address_receive,
'options':options_receive
}
db.thewitch.insert_one(doc)
return jsonify({'result': 'success', 'msg': 'Thank you for your order!'})
# 주문 목록보기(Read) API
@app.route('/order', methods=['GET'])
def view_orders():
orders = list(db.thewitch.find({}, {'_id': False}))
return jsonify({'all_orders': orders})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
index.html
<!doctype html>
<html lang="en">
<head>
<!-- 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>
<title>A24</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@500&family=Raleway:ital,wght@1,200;1,400;1,800&display=swap"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Gothic+A1:wght@100&display=swap" rel="stylesheet">
<style>
* {
font-family: 'Noto Serif KR', serif;
font-family: 'Raleway', sans-serif;
}
.img {
width: 40%;
height: 500px;
margin: 50px auto;
background-image: url(https://cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188);
background-position: center;
background-size: cover;
border: 1px double;
box-shadow: 3px 3px 0px rgb(107, 106, 106);
}
.description {
width: 40%;
margin: auto auto 50px;
}
.title {
font-size: 35px;
font-weight: 800;
}
.price {
font-size: 20px;
font-weight: 400;
margin: 0 0 0 5px;
}
.text {
margin: 25px auto;
color: rgb(140, 139, 139);
font-weight: 200;
}
.order {
width: 40%;
margin: auto auto 100px auto;
}
.input-group-text {
color: black;
background-color: #fff;
border: 1px dashed;
border-radius: 0%;
width: 100px;
text-align: center;
padding-left: 20px;
}
.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),
.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),
.input-group>.input-group-append:not(:last-child)>.btn,
.input-group>.input-group-append:not(:last-child)>.input-group-text,
.input-group>.input-group-prepend>.btn,
.input-group>.input-group-prepend>.input-group-text {
font-weight: 600;
}
.form-control {
border: 1px dashed;
border-radius: 0%;
}
.custom-select {
border: 1px dashed;
border-radius: 0%;
}
.custom-select {
width: 214.39px;
display: inline;
}
.btn-primary {
margin: 20px auto;
border: 1px dashed black;
border-radius: 0%;
background-color: #fff;
color: black;
height: 39px;
width: 100px;
display: block;
}
.btn-primary:hover {
background-color: #fff;
border: 1px solid;
color: black;
}
.orders {
border: 1px dashed;
margin-top: 60px;
}
.table thead th {
border-bottom: 1px dashed #343a40;
}
.table td, .table th {
border-top: none;<!doctype html>
<html lang="en">
<head>
<!-- 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>
<title>A24</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@500&family=Raleway:ital,wght@1,200;1,400;1,800&display=swap"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Gothic+A1:wght@100&display=swap" rel="stylesheet">
<style>
* {
font-family: 'Noto Serif KR', serif;
font-family: 'Raleway', sans-serif;
}
.img {
width: 40%;
height: 500px;
margin: 50px auto;
background-image: url(https://cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188);
background-position: center;
background-size: cover;
border: 1px double;
box-shadow: 3px 3px 0px rgb(107, 106, 106);
}
.description {
width: 40%;
margin: auto auto 50px;
}
.title {
font-size: 35px;
font-weight: 800;
}
.price {
font-size: 20px;
font-weight: 400;
margin: 0 0 0 5px;
}
.text {
margin: 25px auto;
color: rgb(140, 139, 139);
font-weight: 200;
}
.order {
width: 40%;
margin: auto auto 100px auto;
}
.input-group-text {
color: black;
background-color: #fff;
border: 1px dashed;
border-radius: 0%;
width: 100px;
text-align: center;
padding-left: 20px;
}
.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),
.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),
.input-group>.input-group-append:not(:last-child)>.btn,
.input-group>.input-group-append:not(:last-child)>.input-group-text,
.input-group>.input-group-prepend>.btn,
.input-group>.input-group-prepend>.input-group-text {
font-weight: 600;
}
.form-control {
border: 1px dashed;
border-radius: 0%;
}
.custom-select {
border: 1px dashed;
border-radius: 0%;
}
.custom-select {
width: 214.39px;
display: inline;
}
.btn-primary {
margin: 20px auto;
border: 1px dashed black;
border-radius: 0%;
background-color: #fff;
color: black;
height: 39px;
width: 100px;
display: block;
}
.btn-primary:hover {
background-color: #fff;
border: 1px solid;
color: black;
}
.orders {
border: 1px dashed;
margin-top: 60px;
}
.table {
text-align: center;}
}
.table thead th {
border-bottom: 1px dashed #343a40;
}
.table td, .table th {
border-top: none;
text-align: center;
}
</style>
<script>
$(document).ready(function() {
order_listing();
});
function order_listing() {
// 주문목록 보기 API 연결
$.ajax({
type: "GET",
url: "/order",
data: {},
success: function (response) {
let orders = response['all_orders']
for (let i = 0; i < orders.length; i++) {
let name = orders[i]['name']
let options = orders[i]['options']
let phone = orders[i]['phone']
let address = orders[i]['address']
let temp_html = `
<tr>
<td>${name}</td>
<td>${options}</td>
<td>${phone}</td>
<td>${address}</td>
</tr>`
$('#orders-box').append(temp_html)
}
}
})
}
function order() {
// 주문하기 API 연결
let name = $('#inputname').val();
let phone = $('#inputphone').val();
let address = $('#inputaddress').val();
let options = $('#inputGroupSelect01').val();
$.ajax({
type: "POST",
url: "/order",
data: {name_give: name, phone_give: phone, address_give: address, options_give: options},
success: function (response) { // 성공하면
alert(response["msg"]);
}
})
}
</script>
<script>
$(document).ready(function () {
won();
});
function won() {
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/sparta_api/rate",
data: {},
success: function (response) {
let won = response['rate']
$('#rate').append(won)
}
})
}
</script>
</head>
<body>
<div class="img"></div>
<div class="description">
<span class="title">The Witch Screenplay Book</span>
<span class="price">$60</span>
<h4>written and directed by Robert Eggers</h4>
<span id="rate">₩ <span onclick="won()"></span></span>
<p class="text">
Hardcover / 236 pages / 8 x 11 in.<br><br>
Book 002 in the Screenplay Collection features Robert Eggers' meticulously researched script for The Witch ,
along with short fiction by Carmen Maria Machado, a conversation between Eggers and scholar David D. Hall,
and Eggers' own production sketches for the film.
</p>
</div>
<div class="order">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Name</span>
</div>
<input id="inputname" type="text" class="form-control" aria-label="Default"
aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Phone</span>
</div>
<input id="inputphone" type="text" class="form-control" aria-label="Default"
aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Address</span>
</div>
<input id="inputaddress" type="text" class="form-control" aria-label="Default"
aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<label class="input-group-text" for="inputGroupSelect01">Options</label>
</div>
<select class="custom-select" id="inputGroupSelect01">
<option selected>Please choose one.</option>
<option value="1">Standard Edition</option>
<option value="2">Limited Edition</option>
<option value="3">Director's Edition</option>
</select>
</div>
<button onclick="order()" type="button" class="btn btn-primary mybtn">Buy Now</button>
<div class="orders">
<table class="table">
<thead>
<tr>
<th scope="col">name</th>
<th scope="col">options</th>
<th scope="col">phone</th>
<th scope="col">address</th>
</tr>
</thead>
<tbody id="orders-box"></tbody>
</table>
</div>
</div>
</body>
</html>
サマリ
1.クライアントとサーバの確認
2.サーバの作成
3.クライアントの作成
4.完了確認
POSTもGETも同じように処理します!
プロセスの詳細
Ⅰ.デフォルト設定
▸static,templatesフォルダ、app.pyファイルの作成
▸templatesのindex.htmlの生成
インストール▸flask、pymongo(スクロールが必要な場合はbs 4もインストール要求もインストール)
Ⅱ.Buy Now(POST API)
Ⅱ-1.クライアント(index.html)
リクエスト<button onclick="order()" type="button" class="btn btn-primary mybtn">Buy Now</button>
ボタンをクリックして、order関数としてサーバを要求します.
➋ ajax
from flask import Flask, render_template, jsonify, request
app = Flask(__name__)
from pymongo import MongoClient
client = MongoClient('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']
phone_receive = request.form['phone_give']
address_receive = request.form['address_give']
options_receive = request.form['options_give']
doc = {
'name':name_receive,
'phone':phone_receive,
'address':address_receive,
'options':options_receive
}
db.thewitch.insert_one(doc)
return jsonify({'result': 'success', 'msg': 'Thank you for your order!'})
# 주문 목록보기(Read) API
@app.route('/order', methods=['GET'])
def view_orders():
orders = list(db.thewitch.find({}, {'_id': False}))
return jsonify({'all_orders': orders})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
<!doctype html>
<html lang="en">
<head>
<!-- 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>
<title>A24</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@500&family=Raleway:ital,wght@1,200;1,400;1,800&display=swap"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Gothic+A1:wght@100&display=swap" rel="stylesheet">
<style>
* {
font-family: 'Noto Serif KR', serif;
font-family: 'Raleway', sans-serif;
}
.img {
width: 40%;
height: 500px;
margin: 50px auto;
background-image: url(https://cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188);
background-position: center;
background-size: cover;
border: 1px double;
box-shadow: 3px 3px 0px rgb(107, 106, 106);
}
.description {
width: 40%;
margin: auto auto 50px;
}
.title {
font-size: 35px;
font-weight: 800;
}
.price {
font-size: 20px;
font-weight: 400;
margin: 0 0 0 5px;
}
.text {
margin: 25px auto;
color: rgb(140, 139, 139);
font-weight: 200;
}
.order {
width: 40%;
margin: auto auto 100px auto;
}
.input-group-text {
color: black;
background-color: #fff;
border: 1px dashed;
border-radius: 0%;
width: 100px;
text-align: center;
padding-left: 20px;
}
.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),
.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),
.input-group>.input-group-append:not(:last-child)>.btn,
.input-group>.input-group-append:not(:last-child)>.input-group-text,
.input-group>.input-group-prepend>.btn,
.input-group>.input-group-prepend>.input-group-text {
font-weight: 600;
}
.form-control {
border: 1px dashed;
border-radius: 0%;
}
.custom-select {
border: 1px dashed;
border-radius: 0%;
}
.custom-select {
width: 214.39px;
display: inline;
}
.btn-primary {
margin: 20px auto;
border: 1px dashed black;
border-radius: 0%;
background-color: #fff;
color: black;
height: 39px;
width: 100px;
display: block;
}
.btn-primary:hover {
background-color: #fff;
border: 1px solid;
color: black;
}
.orders {
border: 1px dashed;
margin-top: 60px;
}
.table thead th {
border-bottom: 1px dashed #343a40;
}
.table td, .table th {
border-top: none;<!doctype html>
<html lang="en">
<head>
<!-- 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>
<title>A24</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@500&family=Raleway:ital,wght@1,200;1,400;1,800&display=swap"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Gothic+A1:wght@100&display=swap" rel="stylesheet">
<style>
* {
font-family: 'Noto Serif KR', serif;
font-family: 'Raleway', sans-serif;
}
.img {
width: 40%;
height: 500px;
margin: 50px auto;
background-image: url(https://cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//cdn.shopify.com/s/files/1/0023/3789/8540/products/The-Witch-book-share_e38e1f2a-6718-4a53-8a7a-855736967a21.jpg?v=1618330188);
background-position: center;
background-size: cover;
border: 1px double;
box-shadow: 3px 3px 0px rgb(107, 106, 106);
}
.description {
width: 40%;
margin: auto auto 50px;
}
.title {
font-size: 35px;
font-weight: 800;
}
.price {
font-size: 20px;
font-weight: 400;
margin: 0 0 0 5px;
}
.text {
margin: 25px auto;
color: rgb(140, 139, 139);
font-weight: 200;
}
.order {
width: 40%;
margin: auto auto 100px auto;
}
.input-group-text {
color: black;
background-color: #fff;
border: 1px dashed;
border-radius: 0%;
width: 100px;
text-align: center;
padding-left: 20px;
}
.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),
.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),
.input-group>.input-group-append:not(:last-child)>.btn,
.input-group>.input-group-append:not(:last-child)>.input-group-text,
.input-group>.input-group-prepend>.btn,
.input-group>.input-group-prepend>.input-group-text {
font-weight: 600;
}
.form-control {
border: 1px dashed;
border-radius: 0%;
}
.custom-select {
border: 1px dashed;
border-radius: 0%;
}
.custom-select {
width: 214.39px;
display: inline;
}
.btn-primary {
margin: 20px auto;
border: 1px dashed black;
border-radius: 0%;
background-color: #fff;
color: black;
height: 39px;
width: 100px;
display: block;
}
.btn-primary:hover {
background-color: #fff;
border: 1px solid;
color: black;
}
.orders {
border: 1px dashed;
margin-top: 60px;
}
.table {
text-align: center;}
}
.table thead th {
border-bottom: 1px dashed #343a40;
}
.table td, .table th {
border-top: none;
text-align: center;
}
</style>
<script>
$(document).ready(function() {
order_listing();
});
function order_listing() {
// 주문목록 보기 API 연결
$.ajax({
type: "GET",
url: "/order",
data: {},
success: function (response) {
let orders = response['all_orders']
for (let i = 0; i < orders.length; i++) {
let name = orders[i]['name']
let options = orders[i]['options']
let phone = orders[i]['phone']
let address = orders[i]['address']
let temp_html = `
<tr>
<td>${name}</td>
<td>${options}</td>
<td>${phone}</td>
<td>${address}</td>
</tr>`
$('#orders-box').append(temp_html)
}
}
})
}
function order() {
// 주문하기 API 연결
let name = $('#inputname').val();
let phone = $('#inputphone').val();
let address = $('#inputaddress').val();
let options = $('#inputGroupSelect01').val();
$.ajax({
type: "POST",
url: "/order",
data: {name_give: name, phone_give: phone, address_give: address, options_give: options},
success: function (response) { // 성공하면
alert(response["msg"]);
}
})
}
</script>
<script>
$(document).ready(function () {
won();
});
function won() {
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/sparta_api/rate",
data: {},
success: function (response) {
let won = response['rate']
$('#rate').append(won)
}
})
}
</script>
</head>
<body>
<div class="img"></div>
<div class="description">
<span class="title">The Witch Screenplay Book</span>
<span class="price">$60</span>
<h4>written and directed by Robert Eggers</h4>
<span id="rate">₩ <span onclick="won()"></span></span>
<p class="text">
Hardcover / 236 pages / 8 x 11 in.<br><br>
Book 002 in the Screenplay Collection features Robert Eggers' meticulously researched script for The Witch ,
along with short fiction by Carmen Maria Machado, a conversation between Eggers and scholar David D. Hall,
and Eggers' own production sketches for the film.
</p>
</div>
<div class="order">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Name</span>
</div>
<input id="inputname" type="text" class="form-control" aria-label="Default"
aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Phone</span>
</div>
<input id="inputphone" type="text" class="form-control" aria-label="Default"
aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Address</span>
</div>
<input id="inputaddress" type="text" class="form-control" aria-label="Default"
aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<label class="input-group-text" for="inputGroupSelect01">Options</label>
</div>
<select class="custom-select" id="inputGroupSelect01">
<option selected>Please choose one.</option>
<option value="1">Standard Edition</option>
<option value="2">Limited Edition</option>
<option value="3">Director's Edition</option>
</select>
</div>
<button onclick="order()" type="button" class="btn btn-primary mybtn">Buy Now</button>
<div class="orders">
<table class="table">
<thead>
<tr>
<th scope="col">name</th>
<th scope="col">options</th>
<th scope="col">phone</th>
<th scope="col">address</th>
</tr>
</thead>
<tbody id="orders-box"></tbody>
</table>
</div>
</div>
</body>
</html>
1.クライアントとサーバの確認
2.サーバの作成
3.クライアントの作成
4.完了確認
POSTもGETも同じように処理します!
プロセスの詳細
Ⅰ.デフォルト設定
▸static,templatesフォルダ、app.pyファイルの作成
▸templatesのindex.htmlの生成
インストール▸flask、pymongo(スクロールが必要な場合はbs 4もインストール要求もインストール)
Ⅱ.Buy Now(POST API)
Ⅱ-1.クライアント(index.html)
リクエスト<button onclick="order()" type="button" class="btn btn-primary mybtn">Buy Now</button>
ボタンをクリックして、order関数としてサーバを要求します.
➋ ajax
<button onclick="order()" type="button" class="btn btn-primary mybtn">Buy Now</button>
function order() {
$.ajax({
type: "POST",
url: "/order",
data: {},
success: function (response) { // 성공하면
alert(response["msg"]);
}
})
}
@app.route('/order', methods=['POST'])
接続の確認
return jsonify({'result': 'success', 'msg': 'Thank you for your order!'})
Ⅱ-2.サーバ(app.py)
DB insert
@app.route('/order', methods=['POST'])
def save_order():
name_receive = request.form['name_give']
phone_receive = request.form['phone_give']
address_receive = request.form['address_give']
options_receive = request.form['options_give']
doc = {
'name':name_receive,
'phone':phone_receive,
'address':address_receive,
'options':options_receive
}
db.thewitch.insert_one(doc)
サーバからDBに赤い入力値を挿入します.[スパルタコードクラブ]ネットワーク開発総合クラス-第3週(3)を参照してください.
Ⅱ-3.クライアント→サーバ
➊input値の指定
<div class="order">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Name</span>
</div>
<input id="inputname" type="text" class="form-control" aria-label="Default"
aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Phone</span>
</div>
<input id="inputphone" type="text" class="form-control" aria-label="Default"
aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Address</span>
</div>
<input id="inputaddress" type="text" class="form-control" aria-label="Default"
aria-describedby="inputGroup-sizing-default">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<label class="input-group-text" for="inputGroupSelect01">Options</label>
</div>
<select class="custom-select" id="inputGroupSelect01">
<option selected>Please choose one.</option>
<option value="1">Standard Edition</option>
<option value="2">Limited Edition</option>
<option value="3">Director's Edition</option>
</select>
</div>
function order() {
let name = $('#inputname').val();
let phone = $('#inputphone').val();
let address = $('#inputaddress').val();
let options = $('#inputGroupSelect01').val();
関数では、サーバ構築のDBにinput値を送信し、変数として指定するために、inputごとにidを付与します.この場合、「Option」の値はinputではなくcustom-selectであるため、idはcustom-selectに付与される.
入力値の送信
@app.route('/order', methods=['POST'])
def save_order():
name_receive = request.form['name_give']
phone_receive = request.form['phone_give']
address_receive = request.form['address_give']
options_receive = request.form['options_give']
$.ajax({
type: "POST",
url: "/order",
data: {name_give: name, phone_give: phone, address_give: address, options_give: options},
success: function (response) {
alert(response["msg"]);
}
})
}
上で指定した変数をajaxで転送dateは、サーバが受信を決定する名前と一致する必要があります.
を送信するかどうかは、Robo 3 Tを参照してください.
Ⅲ.注文履歴の呼び出し(GET API)
Ⅲ-1.サーバ-クライアント接続
➊クライアント位置決定
$(document).ready(function() {
order_listing();
});
APIをready関数に接続します.ページのロード後、すぐにデータをロードする必要があるためです.➋ ajax
function order_listing() {
$.ajax({
type: "GET",
url: "/order",
data: {},
success: function (response) {
if (response["result"] == "success") {
alert(response["msg"]);
}
}
})
}
GET API要求データ照会であるため、日付値は空です.接続の確認
$(document).ready(function() {
order_listing();
});
⬇︎function order_listing() {
$.ajax({
type: "GET",
url: "/order",
data: {},
success: function (response) {
if (response["result"] == "success") {
alert(response["msg"]);
}
}
})
}
⬇︎@app.route('/order', methods=['GET'])
def view_orders():
orders = list(db.thewitch.find({}, {'_id': False}))
return jsonify({'msg': '이 요청은 GET!'})
クライアントのready関数が動作し、order listingが呼び出されます.クライアント要求を受信したサーバ呼び出しメッセージ.
が正常に呼び出されるとalertウィンドウが停止します
Ⅲ-2.サーバー
@app.route('/order', methods=['GET'])
def view_orders():
orders = list(db.thewitch.find({}, {'_id': False}))
return jsonify({'all_orders': orders})
POST生成DBをロードして戻る「ordersは変数にすぎません.」重要なのはall ordersを降ろすことです.
Ⅲ-3.クライアント
ドア.
function order_listing() {
$.ajax({
type: "GET",
url: "/order",
data: {},
success: function (response) {
let orders = response['all_orders']
for (let i = 0; i < orders.length; i++) {
let name = orders[i]['name']
let options = orders[i]['options']
let phone = orders[i]['phone']
let address = orders[i]['address']
サーバからダウンロードした「all orders」をfor文と呼ぶ❷ orders table
<div class="orders">
<table class="table">
<thead>
<tr>
<th scope="col">name</th>
<th scope="col">options</th>
<th scope="col">phone</th>
<th scope="col">address</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
.
.
.
</tr>
</tbody>
</table>
</div>
Bootstrap Tablesを使用して、Buy Now Buttonの下に受注履歴を送信するテーブルを挿入します. .orders {
border: 1px dashed;
margin-top: 60px;
}
tableとbuttonの間にtableを間隔するordersにmarify-topを与える❸ temp_html
<tbody id="orders-box">
<tr>
<td>1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
.
.
.
</tr>
</tbody>
temp htmlを送信するtbodyにidを指定するlet temp_html = `
<tr>
<td>${name}</td>
<td>${options}</td>
<td>${phone}</td>
<td>${address}</td>
</tr>`
$('#orders-box').append(temp_html)
tableの内容をtemp htmlに挿入する既存の値をfor文の変数に変更
Orders-boxでappend(temp html)に送信
予期せぬ待ち伏せCSS
智旻の下だけにこれだけのスペースを残すのは嫌なので、この部分の空白を取り除きたいのですが、あらゆる方法を使い果たしていても、その部分は思うようにコントロールできません…
last-childを選択!「ヘッダー」を同時に選択
heightを指定します!テーブルが割れた
それ以外は何度も試したが、結果は同じように失敗した.😞
よくできていて、CSSでブロックされたとは思わなかった...OTL
空白を何とか減らそうとしたが、今回の課題のポイントはCSSではないので、そのまま提出した.この部分は個人的に勉強しなければならない.
挑戦試合で授業が遅れたので、今回はミスを詳しく記録できなかった.そこで,処理手順を詳細に記録した.今回の作業は書評例題コードをそのまま応用すればいいだけなので、作業難易度自体は難しくはありませんが、すぐにまた誤りの原因が何なのか訂正し直すので、ちょっと気分が悪いです.私は一人でノートでもう一度練習します.
ちなみにブログもnotionのように切り替え機能を持ってほしいです.完全なコードを一度添付すれば、遊んでいるわけではありません.
Reference
この問題について([スパルタコードクラブ]ネットワーク開発総合クラス-4週間(2)), 我々は、より多くの情報をここで見つけました
https://velog.io/@cinephile/스파르타코딩클럽-웹개발-종합반-4주차2
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
Reference
この問題について([スパルタコードクラブ]ネットワーク開発総合クラス-4週間(2)), 我々は、より多くの情報をここで見つけました https://velog.io/@cinephile/스파르타코딩클럽-웹개발-종합반-4주차2テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol