wisePocket

[Flask] Flask framework 미니프로젝트(project fan) 08 (Backend 응원 댓글 목록 보기 기능 구현 / DB연결) 본문

Python&Flask Tutorials, AWS EB/Flask_project_fan

[Flask] Flask framework 미니프로젝트(project fan) 08 (Backend 응원 댓글 목록 보기 기능 구현 / DB연결)

ohnyong 2023. 7. 18. 11:29

POST 연결 기록하기 기능을 구현했으니 DB에 데이터가 누적되어 저장된다.
이제 해당 웹 페이지가 로드될 때 DB에 저장된 기록된 응원 댓글 목록을 GET 방식으로 불러와서 content 하단 리스트 부분에 보여주고자 한다.
DB에 등록된 닉네임, 응원 댓글 내용을 받아서 View 페이지에 넣어주는 기능을 작성해야 한다.

#### 응원 댓글 목록 확인
- DB에 저장된 기록된 응원 댓글 데이터 받기(find(==read))
- 받은 데이터를 content 부분에 한줄씩 출력

1. 데이터 명세

  • DB : MongoDB
  • Collection : fan
  • Document :
    • 닉네임 : 'name':'name_receive' / from Frontend #name-> formData 'name_give':'value'
    • 응원 댓글 내용 : 'comment':'comment_receive' / from Frontend #comment-> formData 'comment_give':'value'

2. 서버 만들기 및 MongoDB 연결

서버 실행을 위한 라이브러리 임포트와 서버 실행 포트 설정은 GET,POST 기초 테스트에서 이미 작성되었다.

# 라이브러리 임포트
# Flask Framework
# view페이지 렌더링을 위한 render_template 메서드
# 요청 데이터에 접근 할 수 있는 flask.request 모듈
# dictionary를 json형식의 응답 데이터를 내보낼 수 있는 jsonify 메서드
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)

...

# app이라는 메인 함수 
# if __name__ == "__main__" 의 의미는 메인 함수의 선언, 시작을 의미
# 이 파이썬 스크립트가 직접 실행될 때에는 main() 함수를 실행하라
if __name__ == '__main__':
    app.run('0.0.0.0', port=5001, debug=True)
# [POST-3] MongoDB사용을 위한 pymongo와 certifi 임포트
from pymongo import MongoClient
import certifi
# [POST-4] DB 커넥션 구성
ca = certifi.where()
client = MongoClient('mongodb+srv://<account>:test@cluster0.lu7mz8j.mongodb.net/?retryWrites=true&w=majority',tlsCAFile=ca)
db = client.dbsparta

3. 기능 구현을 위한 app.py 부분 수정 및 작성 DB find(Read) 작성

이전 테스트로 서버 시작 및 브라우저로 URL 입력하여 메인 View 페이지 요청에서 GET 요청, 응답 연결되는 것을 확인했기 때문에
우선 app.py부분부터 테스트 코드를 수정하여 원하는 기능을 구현하고자 한다.
개발 순서는 app.py 이후 html을 보며 js를 작성하는 것이 편하지만 요청, 응답, 데이터 흐름 순서는 별도로 표기해 두었다.
 
메인 View 페이지 요청에서 show_comment()의 fetch() 실행 이후

  • [기능 흐름 순서 2]
    • app.py에서 '/guestbook' URL의 GET 방식 요청에 대한 메서드로 접근
    • 이는 guestbook_get()라 선언된 함수를 실행하는데
    • pymongo의 find()를 통해 fan라는 collection의 데이터 document를 모두 찾아냄(읽기)

DB 찾기(읽기) 이후

  • [기능 흐름 순서 3]
    • 불러온 document들을 list() 클래스를 통해 리스트 객체로 변환
    • 리스트 객체를 all_comments라는 변수에 담음
    • all_comments 객체를 jsonify()에 의해 json 형식의 데이터로 변환(주어진 값과 대응하는 JSON 문자열) 후 'result'란 key에 넣어 반환
    • JavaScript로 이동
# [GET-0] CREATE 부분이 테스트 완료되어 DB에 자료가 추가되는 상황, READ로 View 페이지에 DB 데이터를 가져와서 보여주자.
# fetch('URL')부분, 반환값은 res로 전달.
# "localhost:5001/guestbook" URL GET방식 요청에 응답
@app.route("/guestbook", methods=["GET"])
def guestbook_get():
    # [GET-1] 필요한 데이터는? -> DB에서 API 데이터를 가져와야 한다.
    all_comments = list(db.fan.find({},{'_id':False}))
    # [GET-2] 가져온 데이터는? -> json으로 변환하여 반환 -> 프론트(js)로 이동
    return jsonify({'result': all_comments})

4. 기능 구현을 위한 script.js 부분 수정 및 작성

리뷰 목록 보기 기능은 View 페이지가 로드될 때 직후 보이도록 (document).ready()로 설계되었다.
이전 테스트를 통해 script.js에서 GET 요청을 시작하고 최종 응답을 받는 것까지 정상적으로 작동되는 것을 확인했다.
(document).ready()와 연결된 함수인 show_comment() 부분을 작성(수정)한다.
 
View 페이지인 index.html에서 id가 #comment-list인 div태그에 댓글 작성자 이름 name과 응원 댓글 내용인 comment를 DB로부터 찾아 대입한 div>div>blockquote>p+footer 태그가 생성되어야 한다.

서버 시작 및 브라우저로 URL 입력하고 접속을 시작

  •  [기능 흐름 순서 1]
    • URL 요청으로 View 페이지가 반환(load)되면
    • JavaScript (document).ready()가 직후에 즉시 실행 됨
    • 이후 내부 show_comment() 함수 실행
    • show_comment() 내부 fetch()를 통해 '/guestbook' URL에 대한 GET 방식 요청 app.py로 이동
$(document).ready(function () {
    set_temp();
    show_comment();
    show_ranking();
    show_date();
});

...

// [Comment Read]
function show_comment() {
    fetch('/guestbook').then((res) => res.json()).then((data) => {=

DB데이터 찾기(읽기) 이후(fetch() 이후. then() 절로 jsonify 변환 객체가 반환된 이후)

  • [기능 흐름 순서 4]
    • app.py 마지막에서 all_comment 객체를 jsonify()를 통해서 json 형식으로 변환된 데이터
    • 첫 번째 then()절의 res 인자으로 들어감
    • JavaScript로 다시 돌아와서 첫 번째 then()으로 들어간 res는 *response.json()에 의해 Promise 객체로 변환
    • 해당 객체 데이터는 data라는 변수에 담기고
    • 리스트 형태의 data를 rows 변수에 담고
    • ($('#comment-list').empty(); 로 하드코딩된 테이블 부분을 비워줌)
    • 반복문을 통해 1렬씩 [0], [1],... [rows.length]까지 전체를 돌면서 아래 변수에 저장
    • 'name', 'comment' key의 value값들이 name, comment 변수에 담김 
    • temp_html에 위 변수 내용들을 ${name}처럼 출력하는 div>div>blockquote>p+footer 태그 작성
    • index.html에 위 반복문의 결과인 임시 테이블 태그들이 한 줄씩 #comment-list라는 div에 반복문 결과인 리스트가 append 됨
    • (결과 View페이지에서는 DB에 저장된 주문 데이터들이 웹 페이지 하단에 목록 형태로 나타남)
// [Comment Read]
function show_comment() {
    fetch('/guestbook').then((res) => res.json()).then((data) => {
        // json 형식으로 변환, 반환된 데이터가 res 인자로 들어옴
        // res.json()에 의해 Promise 객체로 변환되어 data에 저장
        // data 내용 테스트
        console.log(data)

        // data의 내용이 OpenAPI로부터 데이터 받는것과 동일
        // 리스트 형태의 data를 rows 변수에 담고
        let rows = data['result']
        console.log("rows===>"+rows)

        // 반복문 전에 하드코딩 부분 비워주기
        $('#comment-list').empty();

        // forEach 반복문을 통해
        rows.forEach((a)=>{
            // 리스트에 있는 key의 value들을 각 변수에 담기
            let name = a['name']
            let comment = a['comment']

            console.log("name===>"+name+"\t comment===>"+comment)
            // index.html에 위 변수들이 들어가도록 백틱 내 자리표시자${variable} 작성한 내용을 temp_html에 작성
            let temp_html = `<div class="card">
                                <div class="card-body">
                                    <blockquote class="blockquote mb-0">
                                        <p>${comment}</p>
                                        <footer class="blockquote-footer">${name}</footer>
                                    </blockquote>
                                </div>
                            </div>`
            // 위 temp_html을 index.html의 #comment-list div에 붙여주기.
            $('#comment-list').append(temp_html)
        })
    })
}

5. 테스트

  • Flask 서버가 실행 중인 상태
  • 브라우저에서 localhost:5001 URL로 접속
  • 웹 페이지 로드 직후( (document).ready() 즉시 실행 )
  • 테스트로 insert 했던 4개의 DB 데이터
  • MongoDB내 fan이라는 collection에 테스트 데이터를 불러와지고(Find) content에 목록으로 나열됨


해당 프로젝트는 아래 깃을 통해 업데이트되고 있습니다.

https://github.com/yzpocket/Flask_project_fan

 

GitHub - yzpocket/Flask_project_fan

Contribute to yzpocket/Flask_project_fan development by creating an account on GitHub.

github.com