Wagtail에서 Ajax를 하는 방법에 대해서 기술하려고 한다. 

form 태그와 route 기능을 통해서 서버와 간단한 통신을 할 수 있지만 데이터가 많아지면 한계가 생긴다. 

그래서 route와 Ajax를 이용하여 서버와 클라이언트 간에 데이터 송수신 방법을 소개하려고 한다. 

 

1. JS 작성 

card.js

const card_completion = () => {
    const data = {
        card : card_page_title,
        card_id : card_page_id,
    }

    const url = card_page_url + 'card_completion/';
    const option = {
        method: "POST",
        headers: {
            'X-CSRFToken' : card_page_token,
            "Content-Type": "application/json",
        },
        body: JSON.stringify(data),
    }
    fetch(url, option)
    .then(res => {
        if(res.status === 200){
            res.text()
            .then(text => {
                console.log(text);
            }) 
        }
        else {
            console.log('오류 발생');
        }
    });
}

학습을 완료하고 학습 완료 버튼을 누르면 card_completion 함수가 실행되도록 하려 한다. 

    const data = {
        card : card_page_title,
        card_id : card_page_id,
    }

data에는 서버로 보내고 싶은 데이터를 Json 형식으로 작성해준다. 

    const url = card_page_url + 'card_completion/';
    const option = {
        method: "POST",
        headers: {
            'X-CSRFToken' : card_page_token,
            "Content-Type": "application/json",
        },
        body: JSON.stringify(data),
    }

-url은 서버의 route 주소를 적어준다. Django에서는 꼭 마지막에 '/'을 붙여줘야한다. 

-method는 어떤 방식으로 통신할 것인지를 정해준다. 대표적으로 'GET', 'POST'등이 있다. 

-headers에는 기본 정보가 포함되어 있는데 csrf 토큰과, 전송할 data type을 명시해준다. 

-body에는 위에서 작성한 전송할 데이터를 json 형식 문자열로 바꿔서 작성해준다. 

 

    fetch(url, option)
    .then(res => {
        if(res.status === 200){
            res.text()
            .then(text => {
                console.log(text);
            }) 
        }
        else {
            console.log('오류 발생');
        }
    });

원래는 Jquery Ajax를 사용했는데 요즘은 fetch를 사용한다고 해서 fetch를 사용해보았다. 

res.status가 200이면 정상적으로 통신이 되었다는 의미이므로 통신이 정상적으로 이루어졌을 때에 할 작업들을 작성해주면 된다. 정산적으로 통신이 되었으면 res.text().then을 통해 서버에서 보내온 데이터를 수신한다. 

 

  • response.text() – 응답을 읽고 텍스트를 반환합니다,
  • response.json() – 응답을 JSON 형태로 파싱합니다,
  • response.formData() – 응답을 FormData 객체 형태로 반환합니다. FormData에 대한 자세한 내용은 다음 챕터에서 다루겠습니다.
  • response.blob() – 응답을 Blob(타입이 있는 바이너리 데이터) 형태로 반환합니다.
  • response.arrayBuffer() – 응답을 ArrayBuffer(바이너리 데이터를 로우 레벨 형식으로 표현한 것) 형태로 반환합니다.
  • 이 외에도 response.body가 있는데, ReadableStream 객체인 response.body를 사용하면 응답 본문을 청크 단위로 읽을 수 있습니다. 자세한 용례는 곧 살펴보겠습니다.

https://ko.javascript.info/fetch

 

2. models.py 작성

course/models.py

    @route(r'^card_completion/$', name='card_completion')
    def card_completion(self, request):
        jsonObject = json.loads(request.body)
        card_title = jsonObject.get('card')
        card_id = jsonObject.get('card_id')


        return HttpResponse(json.dumps({'status':'success'}), content_type="application/json")

서버에는 코드가 어떻게 작성되어 있는지를 확인해보자. 기본적인 wagtail의 route랑 같다. 다만 데이터가 json 형식으로 오기 때문에 json.loads를 통해 데이터를 파싱해준다. 데이터는 js에서 보낸 body에 담겨 있다. 

 

그리고 return은 json.dumps를 통해 인코딩을 하고 마찬가지로 content_type을 통해서 전달해준다. 

 

 

3. JQUERY AJAX

 

iamport 기능 구현

let csrftoken = '{{ csrf_token }}'
        IMP.init('imp');
        IMP.request_pay({
            pg: 'html5_inicis',
            pay_method: 'card',
            merchant_uid: 'merchant_' + new Date().getTime(),
            name: '강의 1',
            amount: 100,
            buyer_email: im_email,
            buyer_name: im_name,
            buyer_tel: im_phonenumber,
            buyer_addr: '서울특별시 강남구 삼성동',
            buyer_postcode: '123-456'
        }, function (rsp) {
            if (rsp.success) {
                jQuery.ajax({
                    url: "/api/payment/", 
                    headers:{'X-CSRFToken':csrftoken},
                    type: 'POST',
                    dataType: 'json',
                    contentType: "application/json; charset=utf-8",
                    data: JSON.stringify({
                        imp_uid: rsp.imp_uid,
                        price: 100
                    }),
                }).done(function (data) {
                    alert('성공했습니다.')
                }).fail(function (data) {
                    // 여기에 결제 취소 endpoint를 입력
                    alert(data.message);
                });
            } else {
                var msg = '결제에 실패하였습니다.';
                msg += '에러내용 : ' + rsp.error_msg;
                alert(msg);
            }
        });

 

추가)

HttpResponse, render와 redirect의 차이점에 대해서 알아보자.

 

1. HttpResponse

HttpResponse(data, content_type)

 HttpResponse 는 HttpRequest와 짝을 이루며, response를 반환하는 가장 기본적인 함수

Json이나 html을 반환할 수도 있음.

 

2. render

render(request, template_name, context=None, content_type=None, status=None, using=None)

템플릿과 같이 쓰는 함수이다. context로 정보를 넘겨주면 된다. request 와 template_name 은 필수적으로 필요!

 

3. redirect

redirect(to, permanent=False, *args, **kwargs)

to 에는 어느 URL 로 이동할지를 정하게 됨. 이 때 상대 URL, 절대 URL 모두 가능하며 urls.py 에 name 을 정의하고 이를 많이 사용. 단지 URL로 이동하는 것이기 때문에 render 처럼 context 값을 넘기지는 못함.

 

핵심 : render 는 템플릿을 불러오고, redirect 는 URL로 이동

 

https://valuefactory.tistory.com/605

'Back-End > Wagtail, Django' 카테고리의 다른 글

Wagtail Admin Page 한글 설정  (0) 2021.11.04
Wagtail Form  (0) 2021.11.02
Wagtail Custom Admin Menu  (0) 2021.10.28
Wagtail StreamField Queryset  (0) 2021.10.27
알아두면 좋을 것들  (0) 2021.10.22

+ Recent posts