明日学习団11日制作チャレンジ3日目


3日目([全員の書評]設定~完了/[FE]割当分)

[3日間]FE)割当部分

  • 2日目には、所定のページ構想図に従って、それぞれHTMLコードを作成する部分が割り当てられている.
  • 私が担当している部分はカード部分です
  • 鄭仁の枠組みをもとに行われた.
  • コード-シナリオ(1)
    #CSS
    .card-size {
                background-color: darkgray;
                width: 255.5px;
                height: 300px;
                margin: 0px 32px 40px 0px;
                border-radius: 10px;
            }
    .card-height {
                height: 100%;
    	# 카드마다 다른 길이의 내용때문에 짧아지는 카드 길이 보완
            }
    .card-group {
                width: 1153px;
                height: auto;
                margin-bottom: 40px;
            }
    .card-img {
                width: 237.2px;
                height: 133.9px;
    	# 팀에서 쓰는 api의 이미지 크기를 비율에 맞춰 조금 줄임
                object-fit: contain;
        # width와 height 안쪽으로 이미지 전체가 나오도록 함
                border-radius: 10px;
                margin: 9.1px 9.1px 0px 9.1px;
            }
    .title-over {
    # 타이틀이 길어서 옆으로 빠져나오거나 너비가 달라지지 않도록 생략
                height: 30px;
                width: 220px;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }
    .text-over {
    # 텍스트 길이가 길어져서 빠져나오거나 높이가 달라지지 않도록 생략
                width: 220px;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                font-size: 13px;
            }
    .badge-size {
    #태그를 꾸며주는 badge의 크기를 알맞게 조절
                font-size: 11px;
            }
    # HTML
        <div id="card-group" class="card-group">
            <div id="card" class="card-size">
            # 부트스트랩에서 가져온 카드가 부모 태그 크기에 맞춰지기
              때문에 크기를 잡아줄 부모태그를 만듬.
                <div class="card card-height">
                    <img src="#이미지링크#" class="card-img-top card-img" alt="...">
                    <div class="card-body">
                        <h5 class="card-title title-over">#타이틀#</h5>
                        <p class="card-text text-over">#설명#</p>
                    </div>
                    <div class="card-footer">
                        <small class="text-muted"><span
                                class="badge badge-pill badge-secondary badge-size">#태그#</span></small>
                    </div>
                </div>
            </div>
         </div>
  • 結果:
  • コード-シナリオ(2)
    [事実上、CSS部分のみが変更されているため、CSSのみが添付されている]
    # CSS
    /*<!-- 여기부터 카드섹션  css -->*/
    .card-size {
                background-color: darkgray;
                width: 365px;
                height: 366px;
                	# 카드의 너비, 높이 조금 키움
                margin: 0px 13px 40px 0px;
                	# 오른쪽 마진을 살짝 줄임
                border-radius: 10px;
            }
    .card-height {
                height: 100%;
            }
    .card-group {
                width: 1153px;
                height: auto;
                margin-bottom: 40px;
            }
    .card-img {
                width: 346.75px;
                height: 195.7px;
                	#이미지의 비율을 높임
                object-fit: contain;
                border-radius: 10px;
                margin: 9.1px 9.1px 0px 9.1px;
            }
    .title-over {
                height: 30px;
                width: 320px;
                	# 늘어난 카드 너비에 맞춰 늘림
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }
    .text-over {
                width: 320px;
                	# 늘어난 카드 너비에 맞춰 늘림
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                font-size: 13px;
            }
    .badge-size {
                font-size: 11px;
            }
  • 結果:
  • [1]全員の書評)作業前の設定


    Flashフォルダ構造の作成
    static,templatesフォルダ+app.py
    デフォルトスケルトンの作成
    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 설정
        	# POST
    @app.route('/review', methods=['POST'])
    def write_review():
        sample_receive = request.form['sample_give']
        print(sample_receive)
        return jsonify({'msg': '이 요청은 POST!'})
    	# GET
    @app.route('/review', methods=['GET'])
    def read_reviews():
        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)
    Index.htmlデフォルトスケルトン
    <!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 () {
                    $("#reviews-box").html("");
                    showReview();
                });
                # API와 연결
                # POST
                function makeReview() {
                    $.ajax({
                        type: "POST",
                        url: "/review",
                        data: {sample_give:'샘플데이터'},
                        success: function (response) {
                            alert(response["msg"]);
                            window.location.reload();
                        }
                    })
                }
                # GET
                function showReview() {
                    $.ajax({
                        type: "GET",
                        url: "/review?sample_give=샘플데이터",
                        data: {},
                        success: function (response) {
                            alert(response["msg"]);
                        }
                    })
                }
            </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">
                # API에서 받은 데이터가 들어갈 부분
                        <tr>
                            <td>왕초보 8주 코딩</td>
                            <td>김르탄</td>
                            <td>역시 왕초보 코딩교육의 명가답군요. 따라하다보니 눈 깜짝할 사이에 8주가 지났습니다.</td>
                        </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </body>
    </html> 

    [2]全員の書評)POST練習(コメント保存)


    スケルトンに必要な部分をエンコード
    サーバコード-app.py
    @app.route('/review', methods=['POST'])
    def write_review():
    # 클라이언트가 준 title, author, review 가져오기.
       title_receive = request.form['title_give']
       author_receive = request.form['author_give']
       review_receive = request.form['review_give']
    # DB에 삽입할 review 만들기
       doc = {
           'title':title_receive,
           'author':author_receive,
           'review':review_receive
       }
    # DB에 정보 저장
       db.bookreview.insert_one(doc)
    # 성공했을 때 성공 메시지 반환하기
       return jsonify({'msg': '저장 완료 되었습니다!'})
    クライアントコード-index.html
    function makeReview() {
    // 제목, 저자, 리뷰 내용을 input에서 가져오기
          let title = $('#title').val();
          let author = $('#author').val();
          let review = $('#bookReview').val();
    // POST /review에 저장 요청
          $.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練習(コメント表示)


    スケルトンに必要な部分をエンコード
    サーバコード-app.py
    @app.route('/review', methods=['GET'])
    def read_reviews():
    # DB에서 리뷰 정보 모두 가져오기
       reviews = list(db.bookreview.find({}, {'_id': False}))
    # 2. 성공 시 가져온 리뷰 데이터 반환
       return jsonify({'all_reviews': reviews})
    クライアントコード-index.html
    function showReview() {
                $('#reviews-box').empty();
                $.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.py로 서버를 구동한 뒤에 html과 연결하여 데이터 베이스
    	에 input의 데이터를 가져다 넣는것은 처음에는 굉장히 어려운 작
        	업처럼 느껴졌다. 하지만 강의를 따라 하나하나 해보고 그를 통해
            서 이해해가고 깨달아가는 경험은 정말 특별하고 즐거웠다.
            프로젝트에서는 오늘 3회차 미팅을 거쳐 FE의 역할을 맡아 일단
            카드 섹션 css를 맡았다.
            일단은 코드를 최선을 다해 짜보고 결과도 원하는 대로 나온거 같
            기는한데, 코딩이야 강의를 통해 조금 익숙해졌다지만 이렇게 팀을
            이루어서 하는 프로젝트는 처음이라 그런지 몰라도 영 자신감이 붙
            질않는다. 내가 제대로 해낸건지 어딘가 실수 한것은 아닌지 걱정
            이 태산이다.
            그래도 새로운 경험을 통해서 더욱 내 자신이 성장해가는 것이 느
            껴지기에 기분이 매우 좋다.