wisePocket

[Flask] Flask framework 미니프로젝트(project mars) 06 (Backend 주문하기 기능 구현 / DB설계, DB연결, POST 요청 및 응답, insert) 본문

Python&Flask Tutorials, AWS EB/Flask_project_mars

[Flask] Flask framework 미니프로젝트(project mars) 06 (Backend 주문하기 기능 구현 / DB설계, DB연결, POST 요청 및 응답, insert)

ohnyong 2023. 7. 11. 19:18

GET 및 POST 연결 테스트 메서드의 작동여부가 확인되었으니

클라이언트에서 입력값을 받아 DB에 저장하는 것부터 POST 방식으로 연결하고자 한다.

주문자의 이름, 주소, 땅 수량를 받아서 DB에 넣어주는 기능을 작성해야 한다.

#### 주문진행
- 주문자 이름, 주문자 주소, 주문하고자하는 땅 수량 입력
- '주문하기' 버튼으로 입력값 DB로 전송 및 저장 (insert)

1. 데이터 명세

  • DB : MongoDB
  • Collection : mars
  • Document :
    • 주문자 이름 : 'name':'name_receive' / from Frontend #name-> formData 'name_give':'value'
    • 주문자 주소 : 'address':'address_receive' / from Frontend #address-> formData 'address_give':'value'
    • 주문 땅 수량 : 'size':'size_receive' / from Frontend formData #size-> 'size_give':'value'

2. DB 커넥션

우선 DB에 넣어주어야 하기 때문에 DB를 사용 할 수 있도록

pymongo를 임포트

(MacOS 권한 관련 오류가 뜰 수 있으므로 cetifi를 추가로 설치, 임포트 해주었다.

관련 내용은 https://ohnyong.tistory.com/35)

# MongoDB(Atlas Cloud)를 사용하기 위한 pymongo 임포트
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://<user>:test@cluster0.lu7mz8j.mongodb.net/?retryWrites=true&w=majority',tlsCAFile=ca)
db = client.dbsparta

 

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

이전 연결 테스트로 '주문하기' 버튼이 정상적으로 POST 요청, 응답 연결되는 것을 확인 했기 때문에

우선 app.py부분부터 테스트 코드를 수정하여 원하는 기능을 구현하고자 한다.

개발 순서는 app.py 이후 html을 보며 js를 작성하는 것이 편하지만 요청, 응답, 데이터 흐름 순서는 별도로 표기해두었다.

 

request.form을 통해 요청과 함께 담겨진 body(==formData)를 가져오고 변수에 담는 것을 작성해야 한다

 

  • [기능 흐름 순서 3]
    • body에 담겨서 도착한 데이터들은
    • request.form을 통해 ['key']에 해당되는 value를 가져오고 각 변수 "name_receive", "address_receive", "size_receive"라는 변수에 담는다.
@app.route("/mars", methods=["POST"])
def mars_post():
    # request.form을 통해 요청과 함께 담겨진 body(==formData)를 가져옴
    # sample_receive = request.form['sample_give']
    # print(sample_receive)

    # request.form을 통해 요청과 함께 담겨진 body(==formData)를 가져옴
    # 주문자의 이름, 주소, 땅 수량을 가져온다.
    name_receive = request.form['name_give']
    address_receive = request.form['address_give']
    size_receive = request.form['size_give']
    print(name_receive,address_receive,size_receive)

 

  • [기능 흐름 순서 4]
    • 다음 Dictionary 형식의 리스트 데이터를 갖는 doc이라는 객체 생성
    • 위 변수들에 request.form을 통해 저장한 데이터는 아래 각 value로 들어가고 doc객체 내에 담긴다.
    • 'name':name_receive
    • 'adress':address_receive
    • 'size':size_receive
    • 3개 field 묶음을 가진 객체는 1개의 document가 되며 mars라는 collection 추가(insert_one)하는 부분을 작성

DB 저장 이후

  • [기능 흐름 순서 5]
    • 이후, 확인용으로 {'msg' : 'POST 연결 완료! + DB 저장(insert) 완료!'} 라 하드코딩된 key, value가
    • jsonify()에 의해 json 형식의 데이터로 변환(주어진 값과 대응하는 JSON 문자열) 후 반환하고 js로 이동
    # DB에 넣기 (pymongo 사용 필요)
    # INSERT_ONE
    # 저장 - 예시
    doc ={
        'name':name_receive,
        'address':address_receive,
        'size':size_receive
    }
    db.mars.insert_one(doc)

    return jsonify({'msg':'POST 연결 완료! + DB 저장(insert) 완료!'})

 

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

주문하기 기능은 View 페이지에서 '주문하기' button의 onclick 이벤트로부터 시작되도록 설계되었다.

이전 테스트를 통해 script.js에서 POST 요청을 시작하고 최종 응답을 받는 것 까지 정상적으로 작동되는 것을 확인했다.

이벤트와 연결된 함수인 save_order()부분을 작성(수정)한다.

 

View 페이지인 index.html에서 id가 각 name, address, size로 부터 입력 및 선택 되는 value를 받아와야 한다.

  • [기능 흐름 순서 1]
    • (값들을 입력하고)
    • "주문하기" button의 onclick 이벤트로 JavaScript save_order() 함수 호출
    • JavaScript의 save_order()라는 함수 실행
    • 주문하기 버튼을 누르면(onclick="save_order()")가 실행
    • 값이 입력 된 input, select로부터 value를 가져와야 한다
    • .val()을 통해 각 id에 해당되는 부분의 value를 얻어 name, address, size에 변수에 저장
// [Create]
function save_order() {
    // 프론트엔드 클라이언트로부터 입력값(value) 가져오기
    // index.html의 input태그의 id로부터 value를 각 변수에 담는다.
    let name = $('#name').val()
    let address = $('#address').val()
    let size = $('#size').val()
  • [기능 흐름 순서 2]
    • formData라는 객체를 생성
    • {'name_give':name}, { ... }, { ... } 라는 Dictionary 형식 데이터 .append()를 통해  formData 담기
    • save_order()내부 fetch()를 통해 '/mars' URL에 대한 POST 방식 요청 (+ 위 formData 객체를 body로 추가하여 요청함)
    • app.py로 이동

DB저장 이후(fetch()이후 .then()절로 jsonify 변환 객체가 반환된 이후)

  • [기능 흐름 순서 6]
    • 반환 데이터는 첫번째 then()절의 res 인자값으로 들어감
    • 첫번째 then()으로 들어간 res *response.json()에 의해 Promise 객체로 변환
    • 해당 객체 데이터 data라는 변수에 담기고
    • alert를 통해 key msg의 value인 'POST 연결 완료! + DB 저장(insert) 완료!'가 출력됨. 

 

    let formData = new FormData();
    // formData.append("sample_give", "샘플데이터");
    // formData에 객체를 생성하고
    // append를 통해 ("key", "value")로 데이터를 추가한다.
    formData.append("name_give", name);
    formData.append("address_give", address);
    formData.append("size_give", size);

    // POST 요청에 위 formData를 body에 담아 요청한다.
    fetch('/mars', { method: "POST", body: formData }).then((res) => res.json()).then((data) => {
        // console.log(data);
        alert(data["msg"]);
        // 브라우저 새로고침 추가
        window.location.reload()
    });

5. 테스트

  • Flask 서버가 실행중인 상태
  • 브라우저에서 localhost:5001 URL로 접속
  • 테스트 필드값 입력
    • 이름 : 테스트1
    • 주소 : 서울시 강동구 1번지
    • 평수 : 10평
  • "주문하기" 버튼 클릭
  • 'POST 연결 완료! + DB 저장(insert) 완료!' 알림창

  • MongoDB내 mars라는 collection테스트 데이터가 추가(insert) 됨


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

https://github.com/yzpocket/Flask_project_mars

 

GitHub - yzpocket/Flask_project_mars: [Flask] Flask framework 미니프로젝트(project mars)

[Flask] Flask framework 미니프로젝트(project mars). Contribute to yzpocket/Flask_project_mars development by creating an account on GitHub.

github.com