실습_블로그 구현 (Flask-MySQL를 활용)
이번 실습에서는 Flask와 MySQL을 활용하여 간단한 블로그 시스템을 구현합니다. 블로그 시스템은 사용자에게 게시물을 생성, 조회, 수정 및 삭제할 수 있는 기능을 제공합니다. 아래에서는 전체 코드를 제시한 후, 각 프로세스를 단계별로 설명하겠습니다.
프로젝트 구조
my_flask_app/
│
├── app.py # Flask 애플리케이션 설정 및 라우팅
├── posts_routes.py # 게시물 관련 라우트 처리
├── db.yaml # 데이터베이스 연결 정보
└── templates/
├── posts.html # 게시물 리스트 및 작성 폼
└── post.html # 개별 게시물 표시
블로그 구현 코드 설명
이번 블로그 구현 코드에서는 사용자가 게시물을 생성, 수정, 삭제할 수 있도록 하는 기능을 구현합니다. 코드에는 HTML, JavaScript, 그리고 Axios를 활용한 비동기 HTTP 요청 처리가 포함되어 있습니다. 아래는 각 프로세스에 대한 상세한 설명입니다.
전체 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Blog Posts</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<h1>Blog Posts</h1>
<h2>Create a New Post</h2>
<form id="postForm">
<input type="hidden" id="postId" value="" />
Title: <input type="text" id="title" /><br />
Content:<br />
<textarea id="content"></textarea><br />
<input type="submit" value="Create Post" id="createButton" />
<input
type="button"
value="Update Post"
id="updateButton"
onclick="submitUpdateForm()"
style="display: none"
/>
</form>
<hr />
<h2>All Posts</h2>
<ul id="postsList"></ul>
<script>
let currentEditingId = null;
document
.getElementById("postForm")
.addEventListener("submit", function (e) {
e.preventDefault();
const title = document.getElementById("title").value;
const content = document.getElementById("content").value;
if (currentEditingId === null) {
createNewPost(title, content);
} else {
updatePost(currentEditingId, title, content);
}
});
function createNewPost(title, content) {
axios
.post("/posts", { title, content })
.then(function (response) {
console.log(response);
loadPosts();
resetForm();
})
.catch(function (error) {
console.error(error);
});
}
function updatePost(id, title, content) {
axios
.put("/posts/" + id, { title, content })
.then(function (response) {
console.log(response);
loadPosts();
resetForm();
})
.catch(function (error) {
console.error(error);
});
}
function loadPosts() {
axios
.get("/posts")
.then(function (response) {
const posts = response.data;
const postsList = document.getElementById("postsList");
postsList.innerHTML = "";
posts.reverse().forEach((post) => {
const listItem = document.createElement("li");
listItem.innerHTML = `
<h3>ID: ${post.id}</h3>
<h3>TITLE: ${post.title}</h3>
<p>CONTENT: ${post.content}</p>
<button onclick="deletePost(${post.id})">Delete</button>
<button onclick="loadPostForEditing(${post.id})">Edit</button>
`;
postsList.appendChild(listItem);
});
})
.catch(function (error) {
console.error(error);
});
}
function loadPostForEditing(id) {
axios
.get("/posts/" + id)
.then(function (response) {
const post = response.data;
console.log("post", post);
currentEditingId = post.id;
document.getElementById("title").value = post.title;
document.getElementById("content").value = post.content;
document.getElementById("createButton").style.display = "none";
document.getElementById("updateButton").style.display = "inline";
})
.catch(function (error) {
console.error(error);
});
}
function resetForm() {
currentEditingId = null;
document.getElementById("title").value = "";
document.getElementById("content").value = "";
document.getElementById("createButton").style.display = "inline";
document.getElementById("updateButton").style.display = "none";
}
function submitUpdateForm() {
const title = document.getElementById("title").value;
const content = document.getElementById("content").value;
console.log("currentEditingId", currentEditingId);
if (currentEditingId) {
updatePost(currentEditingId, title, content);
} else {
console.error("No post is currently being edited.");
}
}
function deletePost(id) {
if (confirm("Are you sure you want to delete this post?")) {
axios
.delete("/posts/" + id)
.then(function (response) {
console.log(response);
loadPosts();
})
.catch(function (error) {
console.error(error);
});
}
}
loadPosts();
</script>
</body>
</html>
각 프로세스의 흐름 설명
1. HTML Form 설정
- 목표: 사용자가 새로운 블로그 게시물을 만들거나 기존 게시물을 수정할 수 있는 폼을 제공합니다.
- 코드:
- #postForm: 새로운 게시물을 작성하거나 수정하는 폼입니다.
- Create Post 버튼과 Update Post 버튼이 있으며, 두 버튼은 서로 다르게 표시됩니다.
- Update Post 버튼은 게시물이 수정 중일 때만 표시됩니다.
<form id="postForm">
<input type="hidden" id="postId" value="" />
Title: <input type="text" id="title" /><br />
Content:<br />
<textarea id="content"></textarea><br />
<input type="submit" value="Create Post" id="createButton" />
<input type="button" value="Update Post" id="updateButton" onclick="submitUpdateForm()" style="display: none" />
</form>
2. 게시물 생성 및 수정
- 목표: 사용자가 새 게시물을 생성하거나 기존 게시물을 수정할 수 있습니다.
- 코드:
- submit 이벤트가 발생하면 폼 데이터를 확인하고, currentEditingId가 없으면 새로운 게시물을 생성하고, 있으면 기존 게시물을 수정합니다.
document.getElementById("postForm").addEventListener("submit", function (e) {
e.preventDefault();
const title = document.getElementById("title").value;
const content = document.getElementById("content").value;
if (currentEditingId === null) {
createNewPost(title, content);
} else {
updatePost(currentEditingId, title, content);
}
});
3. 게시물 생성 (createNewPost)
- 목표: 새로운 게시물을 서버에 생성합니다.
- 코드:
- POST /posts API를 호출하여 새 게시물을 생성합니다.
- 성공 시, loadPosts()를 호출하여 게시물 목록을 갱신하고, 폼을 초기화합니다.
function createNewPost(title, content) {
axios.post("/posts", { title, content })
.then(function (response) {
loadPosts();
resetForm();
})
.catch(function (error) {
console.error(error);
});
}
4. 게시물 수정 (updatePost)
- 목표: 기존 게시물을 수정합니다.
- 코드:
- PUT /posts/{id} API를 호출하여 특정 게시물을 수정합니다.
- 수정 후, loadPosts()로 갱신된 게시물 목록을 보여주고, 폼을 초기화합니다.
function updatePost(id, title, content) {
axios.put("/posts/" + id, { title, content })
.then(function (response) {
loadPosts();
resetForm();
})
.catch(function (error) {
console.error(error);
});
}
5. 게시물 목록 불러오기 (loadPosts)
- 목표: 서버에서 모든 게시물을 조회하여 화면에 표시합니다.
- 코드:
- GET /posts를 호출하여 서버에서 게시물 목록을 불러옵니다.
- 불러온 데이터를 화면에 표시하고, 각 게시물에 대한 삭제와 수정 버튼을 생성합니다.
function loadPosts() {
axios.get("/posts")
.then(function (response) {
const posts = response.data;
const postsList = document.getElementById("postsList");
postsList.innerHTML = "";
posts.reverse().forEach((post) => {
const listItem = document.createElement("li");
listItem.innerHTML = `
<h3>ID: ${post.id}</h3>
<h3>TITLE: ${post.title}</h3>
<p>CONTENT: ${post.content}</p>
<button onclick="deletePost(${post.id})">Delete</button>
<button onclick="loadPostForEditing(${post.id})">Edit</button>
`;
postsList.appendChild(listItem);
});
})
.catch(function (error) {
console.error(error);
});
}
6. 게시물 수정 폼 로드 (loadPostForEditing)
- 목표: 게시물을 수정할 때 해당 게시물의 정보를 폼에 로드합니다.
- 코드:
- GET /posts/{id}를 호출하여 특정 게시물을 불러오고, 이를 폼에 채워줍니다.
- Update Post 버튼을 표시하고 Create Post 버튼은 숨깁니다.
function loadPostForEditing(id) {
axios.get("/posts/" + id)
.then(function (response) {
const post = response.data;
currentEditingId = post.id;
document.getElementById("title").value = post.title;
document.getElementById("content").value = post.content;
document.getElementById("createButton").style.display = "none";
document.getElementById("updateButton").style.display = "inline";
})
.catch(function (error) {
console.error(error);
});
}
7. 게시물 삭제 (deletePost)
- 목표: 사용자가 게시물을 삭제할 수 있도록 합니다.
- 코드:
- DELETE /posts/{id}를 호출하여 서버에서 해당 게시물을 삭제합니다.
- 삭제 후, 게시물 목록을 갱신합니다.
function deletePost(id) {
if (confirm("Are you sure you want to delete this post?")) {
axios.delete("/posts/" + id)
.then(function (response) {
loadPosts();
})
.catch(function (error) {
console.error(error);
});
}
}
8. 폼 리셋 (resetForm)
- 목표: 게시물 작성 폼을 초기화합니다.
- 코드:
- 폼 필드를 초기화하고, Create Post 버튼을 다시 표시합니다.
function resetForm() {
currentEditingId = null;
document.getElementById("title").value = "";
document.getElementById("content").value = "";
document.getElementById("createButton").style.display = "inline";
document.getElementById("updateButton").style.display = "none";
}
마무리
이 코드는 HTML, JavaScript, Axios를 활용하여 간단한 CRUD 기능을 갖춘 블로그를 구현합니다. 사용자는 게시물을 추가, 수정, 삭제할 수 있으며, 서버에서 데이터를 불러와 동적으로 처리합니다.
'Flask' 카테고리의 다른 글
Chapter 4-6 실습_블로그 구현 (Flask-MySQL를 활용) posts_routes.py (0) | 2025.04.22 |
---|---|
Chapter 4-4 실습_블로그 구현 (Flask-MySQL를 활용) MySQL 쿼리, db.yaml (0) | 2025.04.22 |
Chapter 4-2 실습_블로그 구현 (Flask-MySQL를 활용) (0) | 2025.04.22 |
Chapter 4-1 Flask-Migrate란? (0) | 2025.04.22 |
Chapter 3-12 Flask 개념 정리 (0) | 2025.04.21 |