TIL Day 82.

Jen Devver·2024년 6월 12일

내배캠 TIL

목록 보기
89/91

Django 최종 팀 프로젝트

프로젝트 마무리

오류 개선

  • 문제: 장바구니의 메뉴 데이터가 결제 후 데이터베이스로 넘어가야 하는데 넘어가지 않음
  • 확인해보니 js의 submitOrder()에서 장바구니 데이터를 받지 않아 생긴 오류: redis에서는 장바구니 상태가 잘 업데이트 되고 있는 것을 확인
  • 따라서 submitOrder()에 장바구니 데이터를 넘겨주기로.
  • 그러면 이 장바구니 데이터는 어디서 가져올 수 있는지? → redis에 장바구니의 상태를 업데이트할 때마다 refreshCart()를 실행하고 있어 refreshCart()로 장바구니 데이터를 넘겨주기로.
  • 자바스크립트의 경우 비동기이므로 단순히 return을 쓰면 되는 것이 아니라 'Promise'로 해주어야 한다고. 정확히 promise가 뭔지 모르겠지만 async await 처럼 동기화해주는 것이라고 이해함.
  • 해결: 따라서 promise 로 처리를 해주고, submitOrder() 안에서 refreshCart()로 장바구니 데이터를 받아 저장해줌.
** 수정 전 **
    function refreshCart() {
        axios.get('/orders/cart/')
        .then(response => {
            const cartData = response.data.cart_items ? response.data.cart_items : {};
            updateCartDisplay(cartData);
        })
        .catch(error => {
            console.error('카트 데이터 fetch 실패:', error);
        });
    }

    function submitOrder() {
        const csrfToken = getCsrfToken();
        console.log("Checking cart contents >>>>>>> ", cart);
        const selectedItems = Object.entries(cartData).map(([name, item]) => {
            console.log(`Parsing item: ${item}`); // 각 item을 파싱하기 전 로그 출력
            if (typeof item === 'string') { 
                item = JSON.parse(item); 
            } 
            return {name: name, count: item.quantity, food_name_ko: item.menu_name};
        });

        // 총 가격 가져오기
        let totalPriceElement = document.getElementById('totalPrice');
        let currentTotal = parseInt(totalPriceElement.textContent.replace('총 가격: ', '', '원'), 10) || 0;

        axios.post("/orders/submit/", JSON.stringify({
            items: selectedItems,
            total: currentTotal
        }), {
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': csrfToken
            }
        }).then(response => {
            window.location.href = '/orders/order_complete/' + response.data.order_number + '/';
        }).catch(error => {
            console.error('Error submitting order:', error);
        });
    }

** 수정 후 **

      function refreshCart() {
        return axios.get('/orders/cart/') // 이렇게 return을 바로 써주는 것이 promise 라고 함..
            .then(response => {
                const cartData = response.data.cart_items ? response.data.cart_items : {};
                updateCartDisplay(cartData);
                return cartData;
            })
            .catch(error => {
                console.error('카트 데이터 fetch 실패:', error);
                return {}; // 오류 발생 시 빈 객체 반환
            });
    }


 function submitOrder() {
        const csrfToken = getCsrfToken();

   // 여기서 이렇게 써주어야 비동기가 되지 않음
        refreshCart().then(cartData => {
            console.log("Received cartData from refreshCart >>>>>>> ", cartData); 
            // 각 아이템을 JSON 파싱 후 올바른 형식으로 변환
            const selectedItems = Object.entries(cartData).map(([name, item]) => {
                console.log(`Parsing item: ${item}`); // 각 item을 파싱하기 전 로그 출력
                if (typeof item === 'string') {
                    item = JSON.parse(item);
                }
                return {
                    id: item.item_id,
                    food_name_ko: item.menu_name,
                    count: item.quantity
                };
            });

            // 총 가격 가져오기
            let totalPriceElement = document.getElementById('totalPrice');
            let currentTotal = parseInt(totalPriceElement.textContent.replace('총 가격: ', '').replace('원', ''), 10) || 0;

            // Axios 요청
            axios.post("/orders/submit/", {
                items: selectedItems,
                total: currentTotal
            }, {
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': csrfToken
                }
            }).then(response => {
                window.location.href = '/orders/order_complete/' + response.data.order_number + '/';
            }).catch(error => {
                console.error('Error submitting order:', error);
            });
        });
    }
  • 다행히 배포 상태에서도 잘 됨. static이 배포 상태로 맞추어져 있어서 html에 js 부분을 다시 넣고, settings.py의 allowed-hosts = ["*"] 와 로컬 DB로 설정해주어서 디버깅했는데 다시 배포 상태로 돌려도 잘 돼서 다행
  • 기존에 로컬에서는 데이터 없이 왜 잘 된 걸까..? 이건 아직도 원인을 모르겠다

배포 흐름 파악

  • 배포에 참여하지 않다보니 어떻게 진행되는지 몰라 진행한 페어의 설명을 부탁드림.
  • 우리 팀 배포: Docker, AWS EC2 이용

UI/UX 관련

  • 사실 백엔드와는 관련이 없지만... 미감을 중시하는 인간으로서 너무 궁금했던 점을 튜터님께 여쭤봄
  • 문제: 현재 메인 화면의 경우 이미지 파일을 넣어둔 거라 세로로 창이 길어질 경우 밑의 흰색이 끝도 없이 길어지는 현상이 발생함
  • 반응형으로 만들면 될 것 같긴 한데 보통 어떤 방법을 쓰지? 하는 생각이 들어서 질문하러 감: 부트스트랩 반응형 그리드 시스템으로 화면을 그리드로 나눴을 때 각 칸에 해당 요소가 들어가도록 구성하거나 미디어 쿼리로 구성하는데 미디어 쿼리의 경우 미디어 쿼리로 한 번 감싸준다고 생각해주면 되고, 이 경우에는 보여지는 크기마다 정해주는.. 일명 노가다의 방식.. 이 된다고 하심.
  • 요즘에는 프론트엔드 개발자들이 보통 하게 된다고. 언젠가 풀스택 개발자로 나아가게 된다면 이런 점도 잘 알아두면 좋을 듯.
profile
발전 중...

0개의 댓글