비밀번호 수정 기능
비밀번호 수정 페이지를 만들기 위해서 먼저 백엔드에서 비밀번호 수정하는 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 ( "이미지 못불러옴" )
}
}