python / flask를 이용한 기본 crud

Duboo·2023년 8월 14일
1
post-thumbnail

파이썬 pip / 가상환경에서 이어지는 내용


/home/user/Projects/flask-tutorial
├── flaskr/
│   ├── __init__.py
│   ├── db.py
│   ├── schema.sql
│   ├── auth.py
│   ├── blog.py
│   |── templates/ <<<< 
│   │   ├── base.html <<<<
│   │   ├── auth/
│   │   │   ├── login.html
│   │   │   └── register.html
│   │   └── blog/
│   │       ├── create.html
│   │       ├── index.html
│   │       └── update.html
│   └── static/
│       └── style.css
├── tests/
│   ├── conftest.py
│   ├── data.sql
│   ├── test_factory.py
│   ├── test_db.py
│   ├── test_auth.py
│   └── test_blog.py
├── .venv/
├── pyproject.toml
└── MANIFEST.in

flask에서 안내하는 프로젝트 마지막의 디렉토리 모습입니다.

templates 디렉토리안에 index.html를 생성하고 app.py에서 연결해줍니다.

Flask 문서확인

from flask import Flask, render_template
app = Flask(__name__)


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

if __name__ == '__main__':
   app.run('0.0.0.0', port=5000, debug=True)

연결 확인

http://localhost:5000에서 html과 app.py가 연결됐는지 확인

<div class="wrap">
	<h1>To Do List</h1>
	<input class="todo-input" type="text" placeholder="todo 입력">
	<input class="update-input" type="text" placeholder="수정">
	<ul class="todo-list"></ul>
</div>

crud에서 가장 기본적인 to do list를 만들어봅니다.
css는 기본적인 틀을 제외하고 생략합니다.


crud / c 생성

데이터를 읽을 수 있는 api를 먼저 작성합니다.
즉, 데이터 저장이 먼저입니다.

클라이언트가 없는 지금 api 요청과 응답을 제대로 확인할 수 없기 때문에 Postman 혹은 vscode의 Thunder Client를 사용합니다.

# 생성 post 요청
@app.route('/createTodo', methods=['POST'])
def toDo_create():
    todo_receive = request.form['todo_give']

    doc = {
        'todo': todo_receive,
    }
    todos.insert_one(doc)
    print('post toDo 저장', doc)
    return jsonify({'msg': 'app.py > post 요청 create'})

서버가 켜져있는지 확인하고 Thunder Client 이용해서 값을 보내고 응답을 확인합니다.

클라이언트에서 값을 보내줄 때 FormData에 담아 보내주기 때문에 Form에 테스트 값을 입력하고 응답을 확인합니다.


crud / r 읽기

# 읽기 get 요청
@app.route("/readToDo", methods=["GET"])
def toDo_get():
    all_todo = list(todos.find({},{'_id':False}))

    return jsonify({'msg': all_todo})

값을 성공적으로 저장했으면 값을 가져와야합니다.


crud / d 삭제

# 삭제 delete 요청
@app.route('/deleteTodo', methods=['DELETE'])
def toDo_delete():
    todo_receive = request.form['todo_give']
    todos.delete_one({'todo': todo_receive})
    return jsonify({'msg': 'app.py > delete 요청'})

현재 todo의 값을 받아와 값에 해당하는 데이터를 삭제합니다.


crud / u 수정

# 수정 post 요청
@app.route('/updateToDo', methods=['POST'])
def toDo_update():
    currentToDo_receive = request.form['current_todo']
    todo_receive = request.form['todo_change']

    todos.update_one({'todo': currentToDo_receive},{'$set':{'todo': todo_receive}})
    return jsonify({'msg': 'app.py > post 요청 update'})

현재 입력된 값을 확인하고 받아와 DB에서 찾은 후 해당 값을 새로운 입력값으로 변경


클라이언트

// 공통 코드

// todo 입력
const toDoInput = document.querySelector(".todo-input");
// todo 변경
const updateInput = document.querySelector(".update-input");
// todo print container
const toDoList = document.querySelector(".todo-list");

// 모든 투두 가져오는 함수
const printAllToDo = () => {
  console.log("printAllToDo 함수 실행");
  const rUrl = "/readToDo";
  fetch(rUrl)
    .then((res) => {
      if (!res.ok) {
        throw new Error(
          `This is an HTTP error: The status is ${response.status}`
        );
      }
      return res.json();
    })
    .then((data) => {
      let toDos = data.msg;
      console.log(data);

      toDos.forEach((todo) => {
        const todoLi = document.createElement("li");
        todoLi.classList.add("todoLi");

        const delSpan = document.createElement("span");
        delSpan.addEventListener("click", deleteToDoFn);
        delSpan.classList.add("del");

        const updateDiv = document.createElement("div");
        updateDiv.addEventListener("click", updateToDo);

        const todoSpan = document.createElement("span");

        updateDiv.innerText = "수정";
        todoSpan.innerText = todo.todo;
        delSpan.innerText = "삭제";

        todoLi.append(todoSpan);
        todoLi.append(delSpan);
        todoLi.append(updateDiv);

        toDoList.append(todoLi);
      });
    })
    .catch((err) => {
      console.log(err.message);
    });
};

// 스크립트 실행시 투두 프린트
printAllToDo();

로드완료시 함수 바로 실행
fetch(get)로 데이터를 가져와 태그를 생성하고 프린트


// 투두 생성 함수
const createTodoFn = () => {
  let inputVal = toDoInput.value;

  let formData = new FormData();
  formData.append("todo_give", inputVal);

  fetch("/createTodo", { method: "POST", body: formData })
    .then((res) => res.json())
    .then((data) => {
      console.log("데이터 생성 완료", data);
      inputVal = null;
      location.reload();
    });
};

// 이벤트
toDoInput.addEventListener("keydown", (e) => {
  if (e.keyCode === 13) {
    createTodoFn();
  }
});

입력값 데이터를 서버로 넘겨줌

// 투두 삭제 함수
const deleteToDoFn = (e) => {
  let deleteToDoVal = e.target.previousSibling.innerText;

  let formData = new FormData();
  formData.append("todo_give", deleteToDoVal);

  fetch("/deleteTodo", { method: "DELETE", body: formData })
    .then((res) => res.json())
    .then(() => {
      location.reload();
    });
};

선택된 데이터를 삭제

// 투두 수정 함수
const updateToDo = (e) => {
  let updateToDo = e.target.previousSibling.previousSibling.innerText;
  const current_todo = updateToDo;

  updateInput.classList.add("show");
  toDoInput.classList.add("close");

  updateInput.focus();
  updateInput.value = updateToDo;

  updateInput.addEventListener("keydown", (e) => {
    if (e.keyCode === 13) {
      let formData = new FormData();
      formData.append("current_todo", current_todo);
      formData.append("todo_change", updateInput.value);

      fetch("/updateToDo", { method: "POST", body: formData })
        .then((res) => res.json())
        .then(() => {
          location.reload();
        });
    }
  });
};

선택된 데이터를 확인하고 변경된 데이터로 변경

profile
둡둡

0개의 댓글