코딩 개발일지

비밀번호 수정 / 북마크한 목록 가져오기 본문

AI 본 교육/AI 11주차

비밀번호 수정 / 북마크한 목록 가져오기

호기호 2023. 10. 30. 11:19

비밀번호 수정 기능

비밀번호 수정 페이지를 만들기 위해서 먼저 백엔드에서 비밀번호 수정하는 views.py를 만들었다.

check_password라는 기능을 이용한것만 빼면 그동안 작성해왔던 코드와 비슷한것을 볼 수 있다.

UseSerializer는 회원가입할 때 썼던 serializer이다.

# 비밀번호 수정
class pwdUpdateView(APIView):
    permission_classes = (IsAuthenticated,)

    def put(self, request):
        user = request.user
        current_password = request.data.get("password_now", "")
        new_password = request.data.get("password", "")
 
        if not user.check_password(current_password):
            return Response({"detail": "현재 비밀번호가 잘못되었습니다."}, status=status.HTTP_401_UNAUTHORIZED)

        serializer = UserSerializer(
            user, data={"password": new_password}, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

당연히 urls.py도 작성해준다.

path('pwdupdate/', views.pwdUpdateView.as_view(), name='pwd_update'),

이제 프론트엔드를 작성하면 기능구현이 완료된다.

먼저 password_update.html을 만들었고, 그 안에 버튼의 onclick="pwdUpdateButton()" 을 만들었다.

그리고 js 파일을 작성해줬다.

async function pwdUpdateButton(){
    const response = await pwdUpdate();
    if (response.status === 200){
        alert("비밀번호가 변경되었습니다.");
        window.location.replace(`${frontend_base_url}`);
    } else if (response.status === 401) {
        alert("현재 비밀번호가 잘못되었습니다. 다시 시도해주세요.");
    } else {
        alert("비밀번호를 변경할 수 없습니다. 다시 시도해주세요.");
    }
    console.log(response);
}

백엔드의 response 값을 받아서 alert창의 내용을 입력해주고, 버튼을 눌렀을 때 pwdUpdate() 함수가 처리될때가지 기다린다는 함수를 정의해준다.

 

이제 pwdUpdate() 함수를 만들어 줘야한다.

앞서 만든 기능들과 마찬가지로 토큰을 이용하기 때문에 토큰값을 받아와주고, html의 password_now와 password 의 id 값을 받아와서 formData에 넣어준다. 그 후 fetch를 통해서 백엔드의 url과 연결해주면 views.py의 put함수가 실행된다.

async function pwdUpdate() {
    let token = localStorage.getItem("access")
   
    const password_now = document.getElementById("password_now").value; // 현재 비밀번호 입력란
    const password = document.getElementById("password").value; // 새 비밀번호 입력란

    const formData = new FormData();
    formData.append("password_now", password_now); // 현재 비밀번호를 추가
    formData.append("password", password); // 새 비밀번호를 추가

    const response = await fetch(`${backend_base_url}/users/pwdupdate/`, {
        method: 'PUT',
        headers: {
            "Authorization": `Bearer ${token}`
        },
        body: formData,
    });

    return response;
}

비밀번호 변경은 사실 그동안 구현해왔던 기능들과 크게 다르지않게 구현해 낼 수 있었던 기능이다.


프론트엔드에서 북마크한 목록 가져오기

북마크 기능을 구현해내는것은 사실 어렵지 않았다. (내 다른 글을 참고하면 쉬울거에용~ 좋아요/북마크/팔로우는 비슷비슷~)

그런데.......!!!!!! 북마크한 목록을 다시 mypage에서 list로 나타내기가 쉽지않았다.

하루종일 이거에 시간 쓴듯...

방황하다가 초심부터 다시 생각해보자는 생각에, 백엔드에서 print를 찍어보면서 북마크의 title을 찍을 수 있으면, 백엔드에서도 가져올 수 있겠다 라는 결론이 나왔다.

 

먼저 postman에서 mypage의 get을 찍어봤다.

여기서 "bookmarks"를 가져오도록 print해주면 된다.

print(serializer.data["bookmark_news"][0]["bookmarks"])

이걸 print해주니 정상적으로 나왔다.

이제 저 값을 프론트엔드에 띄워주기만하면 된다. "bookmarks" 대신 "title"로 띄워주면 완료!

 

이 작업은 메인페이지(index.html)에서 글 목록의 list를 띄워주는 방식을 그대로 사용하면 되겠다는 생각이 들었다.

먼저 북마크 리스트의 api를 가져온다.

// 북마크 리스트 get api
async function getbookmarks() {

    const accessToken = localStorage.getItem("access");
    const response = await fetch(`${backend_base_url}/users/`,{
            method: 'GET',
            headers: {
                Authorization: `Bearer ${accessToken}`,
                'Content-Type': 'application/json',
            }
        })
    if (response.status == 200) {
        const response_json = await response.json()
        return response_json
    } else {
        alert("불러오는데 실패했습니다")
    }
}

mypage.html의 id="bookmark-list" 위치에 북마크 title들을 for문 돌려서 넣어준다.

getbookmarks() 로 북마크한 기사들을 불러오고, 그 기사들의 "bookmark_news" (위에 postman에서 확인 가능) 를 forEach 돌려서 title만 가져오니까 북마크 목록 불러오기를 완료했다.

function articleDetail(article_id) {
    window.location.href = `${frontend_base_url}/article_detail.html?article_id=${article_id}`
}

window.onload = async function fetchUserData() {
    // 게시글을 모두 가져오는 대신, 필요할 때 필터링하여 표시할 배열을 생성합니다.
    const user = await getbookmarks();
    console.log(user["bookmark_news"])
    const bookmark_list = document.getElementById("bookmark-list");
    user["bookmark_news"].forEach(bookmark => {

        const newCol = document.createElement("div");
        newCol.setAttribute("class", "bookmark-div")
        newCol.setAttribute("style", "cursor: pointer;");
        newCol.setAttribute("onclick", `articleDetail(${bookmark.id})`)

        const newCard = document.createElement("div")
        newCard.setAttribute("class", "bookmark-card")
        newCard.setAttribute("id", bookmark.id)
        newCol.appendChild(newCard)

        const newCardtitlecontent = document.createElement("div")
        newCardtitlecontent.setAttribute("class", "bookmark-title")
        newCol.appendChild(newCardtitlecontent)

        const newCardBody = document.createElement("div")
        newCardBody.setAttribute("class", "card-body")
        newCardtitlecontent.appendChild(newCardBody)
        // title
        const newCardTitle = document.createElement("h5")
        newCardTitle.setAttribute("class", "card-title")
        newCardTitle.innerText = bookmark.title
        newCardBody.appendChild(newCardTitle)

        const Cardhr = document.createElement("hr")
        Cardhr.setAttribute("class", "bookmark-hr")
        newCol.appendChild(Cardhr)

        bookmark_list.appendChild(newCol)
       
    })
    document.getElementById("username").textContent = user.username;
    document.getElementById("email").textContent = user.email;
    document.getElementById("mbti").textContent = user.mbti;
   
    const userImage = document.getElementById("profile-image");
    if (user.image) {
        userImage.setAttribute("src", `${backend_base_url}${user.image}/`);
    } else {
        console.error("이미지 못불러옴")
    }
}