[django]倉庫でajax賛機能を実現


将来的にはjQueryを使わずに「いいね」機能を実現しましょう.

🌱ajax賛機能の実現

#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'),
textFieldはboolean値に基づいて変更されます!ソリッドまたは中空
#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>