ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [왕초보]비개발자를 위한, 웹 개발 종합반_4주차
    개발 관련/Front-end 2023. 1. 30. 18:24

    목차

      01. 4주차 오늘 배울 것                                                  

      - HTML과 mongoDB를 연동해서 서버를 만들어봅시다

      4번에 걸친 반복 연습을 진행할 예정입니다!
      그래서 아래와 같은 폴더 구조를 만들고 시작하겠습니다!

      - prac : "flask 연습 코드를 작성합니다."
      -  mars : "화성땅공동구매" 관련 코드를 작성합니다.
      - movie : "스파르타피디아" 관련 코드를 작성합니다.
      - homework : "팬명록" 관련 코드를 작성합니다. 
      - bucket : "버킷리스트" 관련 코드를 작성합니다. (5주차)

      02. Flask 시작하기 

      1) 서버 만들기

      (1) new project → prac 폴더를 선택하고 create 를 클릭합니다.

      (2) Flask 패키지 설치하고 시작! (flask 로 검색한 후, Install package 클릭)

      (3) Flask 기초: 기본 실행 (Flask 프레임워크: 서버를 구동시켜주는 편한 코드 모음. 서버를 구동하려면 필요한 복잡한 일들을 쉽게 가져다 쓸 수 있습니다.)

      (4) 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)

      (5) 이제 크롬에서 http://localhost:5000/ 으로 접속해보고, hello world라는 메세지가 보이면 성공!

       

      👉 [참고] @app.route('/) 부분을 수정해서 URL을 나눌 수 있습니다! 

      단, url 별로 함수명이 같거나, route('/')내의 주소가 같으면 안됩니다.

      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)

      2) HTML 만들기

      • flask 기본 폴더 구조(항상 아래와 같이 세팅하고 시작해야 합니다.)
      Flask 서버를 만들 때, 항상, 프로젝트 폴더 안에,
      ㄴstatic 폴더(이미지, css파일을 넣어둡니다)
      ㄴtemplates 폴더(html파일을 넣어둡니다)
      ㄴapp.py 파일

      이렇게 세 개를 만들어두고 시작하세요. 이제 각 폴더의 역할을 알아봅시다! (꼭 참고!! venv는 실제로는 보이지만,
      안보인다~ 라고 생각하세요! 기억하시죠?)

      3) API 만들기(GET 방식 작성 방법)

      • get / post 방식
      여러 방식이 존재하지만 우리는 가장 많이 쓰이는 GET, POST 방식에 대해 다루겠습니다.

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

      * POST → 통상적으로! 데이터 생성(Create), 변경(Update), 삭제(Delete) 요청 할 때 (예) 회원가입, 회원탈퇴, 비밀번호 수정                → 데이터 전달 : 바로 보이지 않는 HTML body에 key:value 형태로 전달
      • get 요청에서 클라이언트의 데이터를 받는 방법
      예를 들어, 클라이언트에서 서버에 title_give란 키 값으로 데이터를 들고왔다고 생각합시다. (주민등록번호 라는 키 값으로 900120- .. 을 가져온 것과 같은 의미)
      //Jquery 임포트
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      //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)
          }
        })

      4) API 만들기(POST 방식 작성 방법)

      //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)
          }
        })

      03. 화성땅 공동구매

      1) 프로젝트 세팅

      (1) sparta → projects → mars 폴더에서 시작!
      (2) flask 폴더 구조 만들기 (static, templates 폴더 +app.py 만들기! )
      (3) 패키지 설치 (flask, pymongo, dnspython)
       ㄴ 나는 추 후 DB연결을 위해 certifi 라는 패키지를 추가적으로 설치함

      2) 서버, HTML 기본 템플릿 세팅

      //app.py
      
      from flask import Flask, render_template, request, jsonify
      app = Flask(__name__)
      
      @app.route('/')
      def home():
         return render_template('index.html')
      
      @app.route("/mars", methods=["POST"])
      def web_mars_post():
          sample_receive = request.form['sample_give']
          print(sample_receive)
          return jsonify({'msg': 'POST 연결 완료!'})
      
      @app.route("/mars", methods=["GET"])
      def web_mars_get():
          return jsonify({'msg': 'GET 연결 완료!'})
      
      if __name__ == '__main__':
         app.run('0.0.0.0', port=5000, debug=True)
      //index.html
      
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
      
          <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
              integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
          <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
              integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
              crossorigin="anonymous"></script>
      
          <link href="https://fonts.googleapis.com/css2?family=Gowun+Batang:wght@400;700&display=swap" rel="stylesheet">
      
          <title>선착순 공동구매</title>
      
          <style>
              * {
                  font-family: 'Gowun Batang', serif;
                  color: white;
              }
      
              body {
                  background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('https://cdn.aitimes.com/news/photo/202010/132592_129694_3139.jpg');
                  background-position: center;
                  background-size: cover;
              }
      
              h1 {
                  font-weight: bold;
              }
      
              .order {
                  width: 500px;
                  margin: 60px auto 0px auto;
                  padding-bottom: 60px;
              }
      
              .mybtn {
                  width: 100%;
              }
      
              .order > table {
                  margin : 40px 0;
                  font-size: 18px;
              }
      
              option {
                  color: black;
              }
          </style>
          <script>
              $(document).ready(function () {
                  show_order();
              });
              function show_order() {
                  $.ajax({
                      type: 'GET',
                      url: '/mars',
                      data: {},
                      success: function (response) {
                          alert(response['msg'])
                      }
                  });
              }
              function save_order() {
                  $.ajax({
                      type: 'POST',
                      url: '/mars',
                      data: { sample_give:'데이터전송' },
                      success: function (response) {
                          alert(response['msg'])
                      }
                  });
              }
          </script>
      </head>
      <body>
          <div class="mask"></div>
          <div class="order">
              <h1>화성에 땅 사놓기!</h1>
              <h3>가격: 평 당 500원</h3>
              <p>
                  화성에 땅을 사둘 수 있다고?<br/>
                  앞으로 백년 간 오지 않을 기회. 화성에서 즐기는 노후!
              </p>
              <div class="order-info">
                  <div class="input-group mb-3">
                      <span class="input-group-text">이름</span>
                      <input id="name" type="text" class="form-control">
                  </div>
                  <div class="input-group mb-3">
                      <span class="input-group-text">주소</span>
                      <input id="address" type="text" class="form-control">
                  </div>
                  <div class="input-group mb-3">
                      <label class="input-group-text" for="size">평수</label>
                      <select class="form-select" id="size">
                        <option selected>-- 주문 평수 --</option>
                        <option value="10평">10평</option>
                        <option value="20평">20평</option>
                        <option value="30평">30평</option>
                        <option value="40평">40평</option>
                        <option value="50평">50평</option>
                      </select>
                    </div>
                    <button onclick="save_order()" type="button" class="btn btn-warning mybtn">주문하기</button>
              </div>
              <table class="table">
                  <thead>
                    <tr>
                      <th scope="col">이름</th>
                      <th scope="col">주소</th>
                      <th scope="col">평수</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr>
                      <td>홍길동</td>
                      <td>서울시 용산구</td>
                      <td>20평</td>
                    </tr>
                    <tr>
                      <td>임꺽정</td>
                      <td>부산시 동구</td>
                      <td>10평</td>
                    </tr>
                    <tr>
                      <td>세종대왕</td>
                      <td>세종시 대왕구</td>
                      <td>30평</td>
                    </tr>
                  </tbody>
                </table>
          </div>
      </body>
      </html>

      3) POST 넣기(주문/저장)

      1. 요청 정보 : URL= /mars , 요청 방식 = POST
      2. 클라(ajax) → 서버(flask) : name, address, size
      3. 서버(flask) → 클라(ajax) : 메시지를 보냄 (주문 완료!)

      (1) 클라이언트와 서버 연결 확인하기

      //app.py
      
      @app.route("/mars", methods=["POST"])
      def mars_post():
          sample_receive = request.form['sample_give']
          print(sample_receive)
          return jsonify({'msg': 'POST 연결 완료!'})
      //index.html
      
      function save_order() {
          $.ajax({
              type: 'POST',
              url: '/mars',
              data: { sample_give:'데이터전송' },
              success: function (response) {
                  alert(response['msg'])
              }
          });
      }
      
      <button onclick="save_order()" type="button" class="btn btn-warning mybtn">주문하기</button>

      (2) 서버 만들기

      • name, address, size 정보를 받아서, 저장하면 되겠죠?
      • 우리가 일전에 만들어둔 [dbtest.py](<http://dbtest.py>) 파일을 불러와봅시다!
      @app.route("/mars", methods=["POST"])
      def mars_post():
          name_receive = request.form['name_give']
          address_receive = request.form['address_give']
          size_receive = request.form['size_give']
      
          doc = {
              'name': name_receive,
              'address': address_receive,
              'size': size_receive
          }
      
          db.orders.insert_one(doc)
      
          return jsonify({'msg': '주문 완료!'})

      (2) 클라이언트 만들기

      • 이번엔 name, address, size 정보를 보내주면 되겠죠?
      function save_order() {
          let name = $('#name').val()
          let address = $('#address').val()
          let size = $('#size').val()
      
          $.ajax({
              type: 'POST',
              url: '/mars',
              data: { name_give:name, address_give:address, size_give:size },
              success: function (response) {
                  alert(response['msg'])
                  window.location.reload()
              }
          });
      }

      (3) 완성 확인하기(mongoDB cloud 확인)

      4) GET 넣기(주문 보여주기)

      1. 요청 정보 : URL=/mars, 요청 방식 =GET
      2. 클라(ajax) → 서버(flask) : (없음)
      3. 서버(flask) → 클라(ajax) : 전체 주문을 보내주기

      (1) 클라이언트와 서버 연결 확인하기

      //app.py
      
      @app.route("/mars", methods=["GET"])
      def mars_get():
          return jsonify({'msg': 'GET 연결 완료!'})
      //index.html
      
      $(document).ready(function () {
          show_order();
      });
      function show_order() {
          $.ajax({
              type: 'GET',
              url: '/mars',
              data: {},
              success: function (response) {
                  alert(response['msg'])
              }
          });
      }

      (2) 서버 만들기

      @app.route("/mars", methods=["GET"])
      def mars_get():
          orders_list = list(db.orders.find({},{'_id':False}))
          return jsonify({'orders':orders_list})
      //클라이언트 만들기
      
      function show_order() {
          $('#order-box').empty()
          $.ajax({
              type: 'GET',
              url: '/mars',
              data: {},
              success: function (response) {
                  let rows = response['orders']
                  for (let i = 0; i < rows.length; i++) {
                      let name = rows[i]['name']
                      let address = rows[i]['address']
                      let size = rows[i]['size']
      
                      let temp_html = `<tr>
                                          <td>${name}</td>
                                          <td>${address}</td>
                                          <td>${size}</td>
                                        </tr>`
                      $('#order-box').append(temp_html)
                  }
      
              }
          });
      }

      (3) 완성 확인하기

      • 저장하기 눌렀을 때 mongoDB에 잘 저장되었는지 확인하면 끝!

      (4) 전체 코드

      더보기
      //app.py
      
      from flask import Flask, render_template, request, jsonify
      app = Flask(__name__)
      
      from pymongo import MongoClient
      client = MongoClient('내 URL')
      db = client.dbsparta
      
      @app.route('/')
      def home():
         return render_template('index.html')
      
      @app.route("/mars", methods=["POST"])
      def mars_post():
          name_receive = request.form['name_give']
          address_receive = request.form['address_give']
          size_receive = request.form['size_give']
      
          doc = {
              'name': name_receive,
              'address': address_receive,
              'size': size_receive
          }
      
          db.orders.insert_one(doc)
      
          return jsonify({'msg': '주문 완료!'})
      
      @app.route("/mars", methods=["GET"])
      def mars_get():
          orders_list = list(db.orders.find({},{'_id':False}))
          return jsonify({'orders':orders_list})
      
      if __name__ == '__main__':
         app.run('0.0.0.0', port=5000, debug=True)
      //index.html
      
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
      
          <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
              integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
          <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
              integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
              crossorigin="anonymous"></script>
      
          <link href="https://fonts.googleapis.com/css2?family=Gowun+Batang:wght@400;700&display=swap" rel="stylesheet">
      
          <title>선착순 공동구매</title>
      
          <style>
              * {
                  font-family: 'Gowun Batang', serif;
                  color: white;
              }
      
              body {
                  background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('https://cdn.aitimes.com/news/photo/202010/132592_129694_3139.jpg');
                  background-position: center;
                  background-size: cover;
              }
      
              h1 {
                  font-weight: bold;
              }
      
              .order {
                  width: 500px;
                  margin: 60px auto 0px auto;
                  padding-bottom: 60px;
              }
      
              .mybtn {
                  width: 100%;
              }
      
              .order > table {
                  margin : 40px 0;
                  font-size: 18px;
              }
      
              option {
                  color: black;
              }
          </style>
          <script>
              $(document).ready(function () {
                  show_order();
              });
              function show_order() {
                  $('#order-box').empty()
                  $.ajax({
                      type: 'GET',
                      url: '/mars',
                      data: {},
                      success: function (response) {
                          let rows = response['orders']
                          for (let i = 0; i < rows.length; i++) {
                              let name = rows[i]['name']
                              let address = rows[i]['address']
                              let size = rows[i]['size']
      
                              let temp_html = `<tr>
                                                  <td>${name}</td>
                                                  <td>${address}</td>
                                                  <td>${size}</td>
                                                </tr>`
                              $('#order-box').append(temp_html)
                          }
      
                      }
                  });
              }
              function save_order() {
                  let name = $('#name').val()
                  let address = $('#address').val()
                  let size = $('#size').val()
      
                  $.ajax({
                      type: 'POST',
                      url: '/mars',
                      data: { name_give:name, address_give:address, size_give:size },
                      success: function (response) {
                          alert(response['msg'])
                          window.location.reload()
                      }
                  });
              }
          </script>
      </head>
      <body>
          <div class="mask"></div>
          <div class="order">
              <h1>화성에 땅 사놓기!</h1>
              <h3>가격: 평 당 500원</h3>
              <p>
                  화성에 땅을 사둘 수 있다고?<br/>
                  앞으로 백년 간 오지 않을 기회. 화성에서 즐기는 노후!
              </p>
              <div class="order-info">
                  <div class="input-group mb-3">
                      <span class="input-group-text">이름</span>
                      <input id="name" type="text" class="form-control">
                  </div>
                  <div class="input-group mb-3">
                      <span class="input-group-text">주소</span>
                      <input id="address" type="text" class="form-control">
                  </div>
                  <div class="input-group mb-3">
                      <label class="input-group-text" for="size">평수</label>
                      <select class="form-select" id="size">
                        <option selected>-- 주문 평수 --</option>
                        <option value="10평">10평</option>
                        <option value="20평">20평</option>
                        <option value="30평">30평</option>
                        <option value="40평">40평</option>
                        <option value="50평">50평</option>
                      </select>
                    </div>
                    <button onclick="save_order()" type="button" class="btn btn-warning mybtn">주문하기</button>
              </div>
              <table class="table">
                  <thead>
                    <tr>
                      <th scope="col">이름</th>
                      <th scope="col">주소</th>
                      <th scope="col">평수</th>
                    </tr>
                  </thead>
                  <tbody id="order-box">
                    <tr>
                      <td>홍길동</td>
                      <td>서울시 용산구</td>
                      <td>20평</td>
                    </tr>
                    <tr>
                      <td>임꺽정</td>
                      <td>부산시 동구</td>
                      <td>10평</td>
                    </tr>
                    <tr>
                      <td>세종대왕</td>
                      <td>세종시 대왕구</td>
                      <td>30평</td>
                    </tr>
                  </tbody>
                </table>
          </div>
      </body>
      </html>

      04. 스파르타피디아 구현하기

      1) 프로젝트 세팅

      (1) sparta → projects → movie 폴더에서 시작!
      (2) flask 폴더 구조 만들기 (static, templates 폴더 +app.py 만들기! )
      (3) 패키지 설치 (flask, pymongo, dnspython,bs4(크롤링 시 필요), requests(크롤링 시 필요))
       ㄴ 나는 추 후 DB연결을 위해 certifi 라는 패키지를 추가적으로 설치함

      2) 조각 기능 구현하기(meta 태그 스크래핑)

      meta 태그란?
      • 링크에 접속한 뒤 크롬 개발자 도구를 이용해 HTML의 생김새를 살펴볼까요?
      • 메타 태그는, <head></head> 부분에 들어가는, 눈으로 보이는 것(body) 외에 사이트의 속성을 설명해주는 태그들입니다.
      • 예) 구글 검색 시 표시 될 설명문, 사이트 제목, 카톡 공유 시 표시 될 이미지 등
      • 우리는 그 중 og:image / og:title / og:description 을 크롤링 할 예정입니다.

      (1) meta_prac.py 파일을 새로 생성합니다.

      //크롤링 기본 코드
      
      import requests
      from bs4 import BeautifulSoup
      
      url = 'https://movie.naver.com/movie/bi/mi/basic.naver?code=191597'
      
      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,headers=headers)
      
      soup = BeautifulSoup(data.text, 'html.parser')
      
      # 여기에 코딩을 해서 meta tag를 먼저 가져와보겠습니다.

      (2) select_one을 이용해 meta tag를 먼저 가져와봅니다.

      og_image = soup.select_one('meta[property="og:image"]')
      og_title = soup.select_one('meta[property="og:title"]')
      og_description = soup.select_one('meta[property="og:description"]')
      
      print(og_image)
      print(og_title)
      print(og_description)

      (3) 가져온 meta tag의 content를 가져와봅시다.

      image = og_image['content']
      title = og_title['content']
      description = og_description['content']
      
      print(image)
      print(title)
      print(description)

      3) 서버, HTML 기본 템플릿 세팅

      //app.py
      
      from flask import Flask, render_template, request, jsonify
      app = Flask(__name__)
      
      @app.route('/')
      def home():
         return render_template('index.html')
      
      @app.route("/movie", methods=["POST"])
      def movie_post():
          sample_receive = request.form['sample_give']
          print(sample_receive)
          return jsonify({'msg':'POST 연결 완료!'})
      
      @app.route("/movie", methods=["GET"])
      def movie_get():
          return jsonify({'msg':'GET 연결 완료!'})
      
      if __name__ == '__main__':
         app.run('0.0.0.0', port=5000, debug=True)
      //index.html
      
      <!doctype html>
      <html lang="en">
      
      <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      
          <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
                integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
          <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
                  integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
                  crossorigin="anonymous"></script>
      
          <title>스파르타 피디아</title>
      
          <link href="https://fonts.googleapis.com/css2?family=Gowun+Dodum&display=swap" rel="stylesheet">
      
          <style>
              * {
                  font-family: 'Gowun Dodum', sans-serif;
              }
      
              .mytitle {
                  width: 100%;
                  height: 250px;
      
                  background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('https://movie-phinf.pstatic.net/20210715_95/1626338192428gTnJl_JPEG/movie_image.jpg');
                  background-position: center;
                  background-size: cover;
      
                  color: white;
      
                  display: flex;
                  flex-direction: column;
                  align-items: center;
                  justify-content: center;
              }
      
              .mytitle > button {
                  width: 200px;
                  height: 50px;
      
                  background-color: transparent;
                  color: white;
      
                  border-radius: 50px;
                  border: 1px solid white;
      
                  margin-top: 10px;
              }
      
              .mytitle > button:hover {
                  border: 2px solid white;
              }
      
              .mycomment {
                  color: gray;
              }
      
              .mycards {
                  margin: 20px auto 0px auto;
                  width: 95%;
                  max-width: 1200px;
              }
      
              .mypost {
                  width: 95%;
                  max-width: 500px;
                  margin: 20px auto 0px auto;
                  padding: 20px;
                  box-shadow: 0px 0px 3px 0px gray;
      
                  display: none;
              }
      
              .mybtns {
                  display: flex;
                  flex-direction: row;
                  align-items: center;
                  justify-content: center;
      
                  margin-top: 20px;
              }
              .mybtns > button {
                  margin-right: 10px;
              }
          </style>
          <script>
              $(document).ready(function(){
                listing();
              });
      
              function listing() {
                  $.ajax({
                      type: 'GET',
                      url: '/movie',
                      data: {},
                      success: function (response) {
                          alert(response['msg'])
                      }
                  })
              }
      
              function posting() {
                  $.ajax({
                      type: 'POST',
                      url: '/movie',
                      data: {sample_give: '데이터전송'},
                      success: function (response) {
                          alert(response['msg'])
                      }
                  });
              }
      
              function open_box(){
                  $('#post-box').show()
              }
              function close_box(){
                  $('#post-box').hide()
              }
          </script>
      </head>
      
      <body>
      <div class="mytitle">
          <h1>내 생애 최고의 영화들</h1>
          <button onclick="open_box()">영화 기록하기</button>
      </div>
      <div class="mypost" id="post-box">
          <div class="form-floating mb-3">
              <input id="url" type="email" class="form-control" placeholder="name@example.com">
              <label>영화URL</label>
          </div>
          <div class="input-group mb-3">
              <label class="input-group-text" for="inputGroupSelect01">별점</label>
              <select class="form-select" id="star">
                  <option selected>-- 선택하기 --</option>
                  <option value="1">⭐</option>
                  <option value="2">⭐⭐</option>
                  <option value="3">⭐⭐⭐</option>
                  <option value="4">⭐⭐⭐⭐</option>
                  <option value="5">⭐⭐⭐⭐⭐</option>
              </select>
          </div>
          <div class="form-floating">
              <textarea id="comment" class="form-control" placeholder="Leave a comment here"></textarea>
              <label for="floatingTextarea2">코멘트</label>
          </div>
          <div class="mybtns">
              <button onclick="posting()" type="button" class="btn btn-dark">기록하기</button>
              <button onclick="close_box()" type="button" class="btn btn-outline-dark">닫기</button>
          </div>
      </div>
      <div class="mycards">
          <div class="row row-cols-1 row-cols-md-4 g-4" id="cards-box">
              <div class="col">
                  <div class="card h-100">
                      <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                           class="card-img-top">
                      <div class="card-body">
                          <h5 class="card-title">영화 제목이 들어갑니다</h5>
                          <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                          <p>⭐⭐⭐</p>
                          <p class="mycomment">나의 한줄 평을 씁니다</p>
                      </div>
                  </div>
              </div>
              <div class="col">
                  <div class="card h-100">
                      <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                           class="card-img-top">
                      <div class="card-body">
                          <h5 class="card-title">영화 제목이 들어갑니다</h5>
                          <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                          <p>⭐⭐⭐</p>
                          <p class="mycomment">나의 한줄 평을 씁니다</p>
                      </div>
                  </div>
              </div>
              <div class="col">
                  <div class="card h-100">
                      <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                           class="card-img-top">
                      <div class="card-body">
                          <h5 class="card-title">영화 제목이 들어갑니다</h5>
                          <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                          <p>⭐⭐⭐</p>
                          <p class="mycomment">나의 한줄 평을 씁니다</p>
                      </div>
                  </div>
              </div>
              <div class="col">
                  <div class="card h-100">
                      <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                           class="card-img-top">
                      <div class="card-body">
                          <h5 class="card-title">영화 제목이 들어갑니다</h5>
                          <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                          <p>⭐⭐⭐</p>
                          <p class="mycomment">나의 한줄 평을 씁니다</p>
                      </div>
                  </div>
              </div>
          </div>
      </div>
      </body>
      
      </html>

      3) POST 넣기(포스팅하기)

      1. 요청 정보 : URL=/movie, 요청 방식 =POST
      2. 클라(ajax) → 서버(flask) :url,star,comment
      3. 서버(flask) → 클라(ajax) : 메시지를 보냄 (포스팅 완료!)

      (1) 클라이언트와 서버 연결 확인하기 (첫번째 실습, 화성땅 구현에서 post 부분 확인)

      (2) 서버 만들기

      • url, star, comment정보를 받아서, 저장하면 되겠죠?
      • 그리고, 우리가 미리 만든 meta_prac.py도 참고해서 붙여봅시다!
      • 우리가 일전에 만들어둔 [dbtest.py](<http://dbtest.py>) 파일을 불러와봅시다!
      //app.py
      
      @app.route("/movie", methods=["POST"])
      def movie_post():
          url_receive = request.form['url_give']
          star_receive = request.form['star_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')
      
          og_image = soup.select_one('meta[property="og:image"]')
          og_title = soup.select_one('meta[property="og:title"]')
          og_description = soup.select_one('meta[property="og:description"]')
      
          image = og_image['content']
          title = og_title['content']
          description = og_description['content']
      
          doc = {
              'image':image,
              'title':title,
              'desc':description,
              'star':star_receive,
              'comment':comment_receive
          }
      
          db.movies.insert_one(doc)
      
          return jsonify({'msg':'POST 연결 완료!'})

      (3) 클라이언트 만들기

      • 이번엔 url, star, comment정보를 보내주면 되겠죠?
      function posting() {
          let url = $('#url').val()
          let star = $('#star').val()
          let comment = $('#comment').val()
      
          $.ajax({
              type: 'POST',
              url: '/movie',
              data: {url_give: url, star_give: star, comment_give: comment},
              success: function (response) {
                  alert(response['msg'])
                  window.location.reload()
              }
          });
      }

      (4) 완성 확인하기

      • mongoDB에 잘 들어갔는지 확인!

      4) GET 넣기(보여주기)

      1. 요청 정보 : URL=/movie, 요청 방식 =GET
      2. 클라(ajax) → 서버(flask) : (없음)
      3. 서버(flask) → 클라(ajax) : 전체 영화를 보내주기

      (1) 클라이언트와 서버 연결 확인하기 (첫번째 실습, 화성땅 구현에서 get 부분 확인)
      (2) 서버 만들기

      • 받을 것 없이 orders 에 주문정보를 담아서 내려주기만 하면 됩니다!
      @app.route("/movie", methods=["GET"])
      def movie_get():
          movie_list = list(db.movies.find({},{'_id':False}))
          return jsonify({'movies':movie_list})

      (3) 클라이언트 만들기

      • 응답을 잘 받아서 for 문으로! 붙여주면 끝이겠죠!
      function listing() {
          $('#cards-box').empty()
          $.ajax({
              type: 'GET',
              url: '/movie',
              data: {},
              success: function (response) {
                  let rows = response['movies']
                  for(let i = 0; i < rows.length; i++) {
                      let image = rows[i]['image']
                      let title = rows[i]['title']
                      let desc = rows[i]['desc']
                      let star = rows[i]['star']
                      let comment = rows[i]['comment']
      
                      let star_image = '⭐'.repeat(star)
      
                      let temp_html = `<div class="col">
                                          <div class="card h-100">
                                              <img src="${image}"
                                                   class="card-img-top">
                                              <div class="card-body">
                                                  <h5 class="card-title">${title}</h5>
                                                  <p class="card-text">${desc}</p>
                                                  <p>${star_image}</p>
                                                  <p class="mycomment">${comment}</p>
                                              </div>
                                          </div>
                                      </div>`
      
                      $('#cards-box').append(temp_html)
                  }
              }
          })
      }

      (4) 완성 확인하기

      • 화면을 새로고침 했을 때, DB에 저장된 리뷰가 화면에 올바르게 나타나는지 확인합니다.

      댓글

    Designed by Tistory.