window.onload = async function loadUpdatePost() {
const urlParams = new URLSearchParams(window.location.search);
const postId = urlParams.get("post_id");
const exist_post = await getPost(postId);
// 원래 제목 띄우기
const updateTitle = document.getElementById("update-title")
updateTitle.value = exist_post.title
// 원래 내용 띄우기
const updateContent = document.getElementById("update-content")
updateContent.value = exist_post.content
...
}
수정창이 로드되었을 때 해당 함수가 실행된다
수정창 url에는 파라미터로 post_id가 담겨있다
url에서 post_id를 추출해서 getPost 함수의 매개변수에 담아 게시글을 가져왔다
html의 아이디가 update-title인 부분의 값에 원래 게시글의 제목을 담았다
내용도 똑같이 했다
이제 문제는 이미지와 별이다
이 상태에서 수정창을 켜면 별은 선택이 안 되어 있어서 이용자는 별점을 수정하고 싶지 않아도 수정해야 하는 상황에 처한다
그리고 이미지가 있는 게시글이었는데 이미지 선택을 안 하고 그냥 수정을 누르면 이미지가 사라진다
- 별 색칠하기
...
//원래 별 띄우기
for (let i = 1; i <= exist_post.star; i++) {
document.getElementById(`rating${i}`).checked = true;
}
....
html에 별 태그 각각 id는 rating1, rating2 이런 식으로 되어 있다
우선 데이터베이스에 저장된 star값을 가져와서 for문을 돌린다
1부터 해당하는 star 값까지 1씩 증가하면서 for문이 도는데 그때마다 html에 rating(star값) 아이디를 가진 태그 부분에 checked를 true로 바꿔준다
게시글 상세창에서 수정 버튼을 눌렀을 때 별이 제대로 색칠되어 있는 것을 확인할 수 있다(제목, 내용도 제대로 들어온다)
- 별 다시 선택하지 않았을 때 Bad Request 뜨는 오류
별이 색칠되어 있지만 현재 코드는 별을 클릭해야 저장이 되는 방식으로 되어 있다
그래서 별을 선택하지 않으면 아무리 색칠이 되어 있어도 null 값이 뜬다
별을 고치지 않았을 때 null 값을 별이 색칠된 수만큼의 값을 넣어줘야 한다
그 말은 원래 데이터베이스에 있던 star 값을 그대로 유지하면 된다는 것이다
// api.js
// 게시글 수정
async function updatePosts(url) {
const urlParams = new URLSearchParams(url);
const postId = urlParams.get("post_id");
const exits_post = getPost(PostId);
...
// 별 클릭 안 했을 때 원래 star에 있던 데이터 다시 저장하는 코드
if (star == null) {
star = exist_post.star
}
...
}
그래서 이 코드를 추가했다
별을 다시 선택한 경우에는 게시글 작성과 마찬가지로 html의 value값을 가져와서 저장한다
- 이미지 새로 첨부하지 않았을 때 기존 이미지 그대로 두기
게시글 수정 기능을 구현하고 테스트를 하다가 원래 이미지가 있던 게시글인데 이미지를 선택하지 않았더니 이미지가 사라지는 오류를 발견했다
수정값을 받아서 백엔드로 데이터를 전송하는 부분에서 오류가 있는 것 같았다
// api.js
// 게시글 수정
async function updatePosts(url) {
...
const formdata = new FormData();
// 사진 새로 선택한 경우에만 formdata에 이미지 붙이기(안 하면 원래 데이터베이스에 이미지 그대로 있게 함)
if (img) {
formdata.append("image", img)
}
formdata.append("title", title)
formdata.append("content", content)
formdata.append("star", star)
...
}
formdata에 제목, 내용, 별은 그대로 붙여지고 사진은 값이 새로 들어온 경우에만 붙이는 걸로 로직을 수정했다
별 수정한 것처럼 사진이 undefined인 경우에 원래 데이터베이스에 있는 값을 그대로 저장하려고 했는데 이미 저장된 이미지를 굳이 다시 꺼내서 저장할 필요가 없고 그렇게 되지도 않았다 ㅋㅋㅋ
star 한대로 exist_post.image 했는데 files[0]와 같은 형식이 아니어서 bad request 에러가 뜬다
근데 이렇게 하고 보니까 star도 값을 새로 넣어서 formdata에 붙일 필요없이 star가 있는 경우에 붙이는 걸로 했어도 됐을 것 같다
exist_post 빼고 이미지 한 것처럼 수정해야겠다~
// api.js
// 게시글 수정
async function updatePosts(url) {
const urlParams = new URLSearchParams(url);
const postId = urlParams.get("post_id");
const title = document.getElementById('update-title').value
const content = document.getElementById('update-content').value
let img = document.getElementById('update-image').files[0]
let star = document.getElementById('star').getAttribute('value')
const formdata = new FormData();
formdata.append("title", title)
formdata.append("content", content)
// 사진 새로 선택한 경우에만 formdata에 이미지 붙이기(안 하면 원래 데이터베이스에 이미지 그대로 있게 함)
if (img) {
formdata.append("image", img)
}
// 별을 새로 선택한 경우에만 formdata에 데이터 붙이기(클릭 안 한 경우 원래 데이터베이스에 star 값 그대로 있게 함)
if (star) {
formdata.append("star", star)
}
let token = localStorage.getItem("access")
const response = await fetch(`${backend_base_url}/posts/${postId}/`, {
headers: {
'Authorization': `Bearer ${token}`
},
method: 'PUT',
body: formdata
})
if (response.status == 200) {
alert("글 수정 완료")
window.location.replace(`${frontend_base_url}/posts/post_detail.html?post_id=${postId}`)
} else if (title == '' || content == '') {
alert("빈칸을 입력해 주세요.")
} else {
alert(response.statusText)
}
}
<메인페이지 구현하기>
원래 기획했던 대로 구현하지는 못 하고 그냥 메인페이지에 최근 글 10개가 뜨게끔 했다..