본문 바로가기
[스파르타 코딩클럽]/비개발자를 위한, 웹개발 종합반

스파르타피디아 - GET -

by 수민띠 2023. 2. 26.

포스트 보여주기 API 만들기(GET)

로딩이 완료되면 자동으로 카드가 붙는 기능
로딩이 완료되면 fetch를 날려서 결과를 가지고 카드를 붙여주는 기능
 
데이터 명세
요청 정보: URL = /movie, 요청 방식 = GET
클라(fetch) → 서버(flask) : 없음
서버(flask) → 클라(fetch) : 전체 주문 보내주기
 
클라이언트와 서버 연결 확인하기

웹에 접속했을 때 서버로부터 메시지를 받는지 확인

 
서버 만들기
받을 것 없이 DB에서 주문정보만 변수에 담아서 클라이언트한테 보낸다.

@app.route("/movie", methods=["GET"])
def movie_get():
    all_movies = list(db.movies.find({},{'_id':False}))
    return jsonify({'result': all_movies})

 
클라이언트 만들기

step1. 서버한테 받은 데이터 console에 확인해 보기

step2. 받은 데이터 저장하기 ※서버한테 객체로 받은 점 유의

step3. forEach로 데이터 뽑기

step4. 추가할 요소 만들고 변수에 저장하기

step5. 요소 추가하기 - jQuery

step6. 새로고침 (기존 html코드를 지우는 용도)

    $(document).ready(function () { //페이지 로딩시 실행됨
      listing();
    });

    function listing() { //get요청
      fetch('/movie').then((res) => res.json()).then((data) => {
        console.log(data)
        let rows = data['result'];
        $('#cards-box').empty();
        rows.forEach((a) => {
          let comment = a['comment']
          let desc = a['desc']
          let image = a['image']
          let title = a['title']

          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>⭐⭐⭐</p>
                                    <p class="mycomment">${comment}</p>
                                </div>
                              </div>
                          </div>`
          $('#cards-box').append(temp_html);
        })
      })
    }

 

동작 확인
화면을 새로고침 했을 때, 기록한 영화가 화면에 올바르게 나타나는지 확인

 

별점이 3개로 나오는 것과 영화기록하기에서 별점추가하는 부분까지 구현한 전체 코드
app.py

더보기
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)

from pymongo import MongoClient
client = MongoClient('mongodb+srv://sparta:test@sumin.hf0ef61.mongodb.net/?retryWrites=true&w=majority')
db = client.dbsparta

import requests
from bs4 import BeautifulSoup

@app.route('/')
def home():
    return render_template('index.html')

@app.route("/movie", methods=["POST"])
def movie_post():
    url_receive = request.form['url_give']
    comment_receive = request.form['comment_give']
    comment_star = request.form['star_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) #받은 url

    soup = BeautifulSoup(data.text, 'html.parser')

    ogtitle = soup.select_one('meta[property="og:title"]')['content']
    ogdesc = soup.select_one('meta[property="og:description"]')['content']
    ogimage = soup.select_one('meta[property="og:image"]')['content']

    doc = {
        'title' : ogtitle,
        'desc' : ogdesc,
        'image' : ogimage,
        'comment' : comment_receive,
        'star' : comment_star
    }
    db.movies.insert_one(doc)
    
    return jsonify({'msg':'저장 완료'})

@app.route("/movie", methods=["GET"])
def movie_get():
    all_movies = list(db.movies.find({},{'_id':False}))
    return jsonify({'result':all_movies})

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() {
      fetch('/movie').then((res) => res.json()).then((data) => {
        let rows = data['result']
        $('#cards-box').empty()
        rows.forEach((a) => {
          console.log(a)
          let comment = a['comment']
          let title = a['title']
          let desc = a['desc']
          let image = a['image']
          let star = a['star']

          let star_repeat = '⭐'.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_repeat}</p>
                                  <p class="mycomment">${comment}</p>
                                </div>
                              </div>
                            </div>`
          $('#cards-box').append(temp_html)
        })
      })
    }

    function posting() {
      let url = $('#url').val()
      let comment = $('#comment').val()
      let star = $('#star').val()

      let formData = new FormData();
      formData.append("url_give", url);
      formData.append("comment_give", comment);
      formData.append("star_give",star)

      fetch('/movie', { method: "POST", body: formData }).then((res) => res.json()).then((data) => {
        alert(data['msg'])
        window.location.reload()
      })
    }

    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>