コード学習第四


Pythonを用いてフラスコサーバを作成し,サーバとクライアントの基礎を学習した.

Flashサーバ


フラスコベース


フラスコ起動コード
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)
終了方法
ターミナルウィンドウをクリックしてctrl+cでサーバを終了
フラスコのデフォルトフォルダ構造
Flashサーバを作成するときは、常に次のようにします.
プロジェクトフォルダで、
静的フォルダ(画像、cssファイルが暗い)
ㄴtemplatesフォルダ(htmlファイルを非表示)
ㄴapp.pyファイル
htmlファイルを読み込む
各URLの関数名は同じです.
アドレスはroute('/')などと同じではありません.
from flask import Flask, render_template
app = Flask(__name__)
@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
    →通常!データ照会要求時
    例)ムービーリストの表示
    →データ転送:URLの後ろに疑問符を付けてkey=valueに転送する
    →例:google.com?q=ホッキョクグマ
  • POST
    →通常!作成、更新、削除を要求します.
    例)会員加入、会員脱退、パスワード修正
    →データ転送:非表示HTML bodyでkey:value形式で
  • を転送
    GET要求APIコード
    @app.route('/test', methods=['GET'])
    def test_get():
    	title_receive = 	request.args.get('title_give')
    	print(title_receive)
    	return jsonify({'result':'success', 'msg': '이 요청은 GET!'})
    GET要求確認Ajaxコード
    $.ajax({
    	type: "GET",
    	url: "/test?title_give=봄날은간다",
    	data: {},
    	success: function(response){
    		console.log(response)
    	}
    })
    POST要求APIコード
    @app.route('/test', methods=['POST'])
    def test_post():
    	title_receive = request.form['title_give']
    	print(title_receive)
    	return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
    POST要求確認Ajaxコード
    $.ajax({
    	type: "POST",
    	url: "/test",
    	data: { title_give:'봄날은간다' },
    	success: function(response){
    		console.log(response)
    	}
    })

    練習のために[すべての人の書評]を作成する


    1.サーバーの作成(POST)


    app.pyでのサーバの作成
    コメントの作成に必要な情報は、次の3つです.
  • タイトル(title)
  • 著者(著者)
  • コメント(コメント)
    したがって、API機能は、以下の3つのステップを含む必要があります.
  • クライアントが提供するtitle、author、reviewをインポートします.
  • DBに情報
  • を挿入する.
  • が成功したかどうか&成功メッセージ
  • を返す
    A.要求情報
    要求URL=/レビュー、要求方式=POST
    要求されたデータ:タイトル(title)、著者(author)、コメント(review)
    B.サーバが提供する機能:クライアントに要求データをデータベース作成(Create)に送信し、応答データを送信し、保存に成功したことを示す
    C.応答データ:(JSON形式)「msg」=「コメント作成に成功しました.」
    @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': '리뷰가 성공적으로 작성되었습니다.'})

    2.クライアントの作成(POST)


    コメントの作成に必要な情報は、次の3つです.
  • タイトル(title)
  • 著者(著者)
  • コメント(コメント)
    したがって、クライアント・コードには、次の3つのステップが含まれている必要があります.
  • inputからtitle、author、review
  • をインポート
    入力値
  • がない場合はalertが表示されます.
  • サーバを
  • Ajaxに保存し、画面
  • を再ロードするように要求する.
    A.要求情報
    要求URL=/レビュー、要求方式=POST
    要求されたデータ:タイトル(title)、著者(author)、コメント(review)
    B.サーバが提供する機能:データベースにクライアントに送信する要求データを作成し、正常に保存する
    レスポンスデータの送信
    C.応答データ:(JSON形式)「result」=「success」、「msg」=「コメント作成成功」.
    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();
    		}
    	})
    }

    3.サーバの作成(GET)


    API機能には、次のステップが含まれます.
    1.データベースからすべてのコメント情報を取得
    2.成功したかどうか&コメントリストに戻る
    A.要求情報
    要求URL=/review,要求方式=GET
    要求データ:なし
    B.サーバが提供する機能:データベースでコメント情報を検索し、成功メッセージとコメント情報の応答データを送信する
    C.応答データ:(JSON形式)「result」=「success」、「reviews」=コメントリスト
    @app.route('/review', methods=['GET'])
    def read_reviews():
    	reviews = list(db.bookreview.find({}, {'_id': False}))
    	return jsonify({'all_reviews': reviews})

    4.クライアントの作成(GET)


    コメントの作成に必要な情報は、次の3つです.
  • タイトル(title)
  • 著者(著者)
  • コメント(コメント)
    したがって、クライアント・コードには、次の3つのステップが含まれている必要があります.
  • サーバ要求
  • コメントリスト
  • リクエストが成功したかどうかを確認する
  • リクエストが成功した場合にコメントを正しく表示
    A.要求情報
    要求URL=/review,要求方式=GET
    要求データ:なし
    B.サーバが提供する機能:データベースでコメント情報を表示し、成功メッセージとコメント情報の応答データを表示する
    におい
    C.応答データ:(JSON形式)「all reviews」=コメントリスト
  • 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)
    			}
    		}
    	})
    }

    5.完成本

    from flask import Flask, render_template, jsonify, request
    app = Flask(__name__)
    from pymongo import MongoClient
    client = MongoClient('localhost', 27017)
    db = client.dbsparta
    @app.route('/')
    def home():
    	return render_template('index.html')
    @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.jp
    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>

    meta tag


    MetaTagは、部分的に肉眼的に見える(body)を除いて、サイトの属性を記述するタグのセットである.
    例og:image/og:title/og:description