장고에서 jQuery를 사용하지 않고 좋아요 기능 구현해보자!
#models.py
class Post(models.Model):
title = models.CharField(verbose_name='제목',max_length=30)
content = models.TextField(verbose_name='내용')
like = models.TextField(default= '<i class="far fa-heart"></i> ')
already_like = models.BooleanField(default=False)
# urls.py
path('like_ajax/',views.like_ajax, name='like_ajax'),
boolean값에 따라서 textField가 바뀐다! 채워진 하트 or 빈 하트
#views.py
#좋아요기능
@csrf_exempt
def like_ajax(request):
req = json.loads(request.body)
post_id = req['id']
post = Post.objects.get(id = post_id)
if post.already_like == True: #좋아요가 눌러져있으면
post.already_like = False
status = post.already_like
post.like = '<i class="far fa-heart"></i> '
message = "좋아요 취소"
else: #좋아요가 안눌러져있으면
post.already_like = True
status = post.already_like
post.like = ' <i class="fas fa-heart" style="color:red"></i>'
message = "좋아요"
post.save()
return JsonResponse({'id': post_id, 'message': message, 'status':status})
#templates
<script> //1️⃣
const requestLike = new XMLHttpRequest();
const onClickLike = (id) => { //파라미터로 서버로 보낼 데이터의 id(포스트 id)
const url = '/like_ajax/'; 요청을 보낼 url -> urls.py에 등록해야함
requestLike.open("POST", url, true); //POST 방식으로 비동기로 서버에 요청
requestLike.setRequestHeader( / header에 포함하고자하는 내용들
"Content-Type",
"application/x-ww-form-urlencoded"
);
requestLike.send(JSON.stringify({id: id})) //JSON 형태로 id와 type를(데이터를) 서버에 보내기(요청)
}
// 서버에서 request 처리를 해서 다시 클라이언트로 보내준 것
requestLike.onreadystatechange = () => {
if(requestLike.readyState === XMLHttpRequest.DONE){ // requestLike의 값이 변할때마다 자동으로 실행됨
likeHandleResponse(); //응답받을 준비가 완료
}
}
//views.py에서 post.like +=1한거는 데이터(DB)에만 반영돼서
// 새로고침없이 html에서 보이는 값을 바꾸기 위해서 js에서 Number(num) + 1을 하는 것
const likeHandleResponse = () => {
if(requestLike.status < 400){ // 상태값이 정상적임(에러아님)
const {id, message, status} = JSON.parse(requestLike.response); // 서버에서 들어온 JSON 응답값을 다시 자바스크립트에서 쓸 수 있게 형변환
const element = document.querySelector(`.post-id-${id} .post__like`);
console.log(message)
console.log(status)
if( message == "좋아요")
element.innerHTML = '<i class="fas fa-heart" style="color:red"></i>' //채워진하트
else
element.innerHTML = '<i class="far fa-heart"></i> '//빈하트
}
}
</script>
<script> //2️⃣Fetch API 사용
const onClickLike = async(id) => { //async : 전체적인 비동기 처리 ❗ await로 쓴 부분은 동기처리
const url = "/like_ajax/"
const res = await fetch(url,{ // url에 있는 서버에 {} 내용을 보냄. body에 있는 데이터를 보냄
method : 'POST',
headers : {
'Content-Type' : 'application/x-ww-form-urlencoded'
},
body: JSON.stringify({id:id})
});
const {id:postId} = await res.json(); //요청이 보낸 후 응답받는 코드, await로 동기적으로 응답받음
likeHandleResponse(postId);
}
const likeHandleResponse = (id) => {
const element = document.querySelector(`.post-id-${id} .post__like`);
console.log(message)
console.log(status)
if( message == "좋아요")
element.innerHTML = '<i class="fas fa-heart" style="color:red"></i>' //채워진하트
else
element.innerHTML = '<i class="far fa-heart"></i> '//빈하트`
};
</script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script> //3️⃣axios 사용
const onClickLike = async (id) => {
const url = "/like_ajax/";
const {data} = await axios.post(url,{ //POST 방식으로 url요청해서 서버에 id와 type을 보냄, 그리고 응답을 data 변수 안에 넣음
id
});
likeHandleResponse(data.id);
}
const likeHandleResponse = (id) => {
const element = document.querySelector(`.post-id-${id} .post__like`);
console.log(message)
console.log(status)
if( message == "좋아요")
element.innerHTML = '<i class="fas fa-heart" style="color:red"></i>' //채워진하트
else
element.innerHTML = '<i class="far fa-heart"></i> '//빈하트`
};
</script>