장고 기반生鲜 쇼핑몰: 주문 리뷰 기능 구현

주문 페이지 자바스크립트 구현

주문 상태에 따라 다음 단계 작업을 표시합니다. 사용자가 '리뷰 작성'을 클릭하면 location.href= '/order/comment/'+order_id를 통해 주문 리뷰 URL로 이동합니다.

    // 주문 상태에 따라 다음 작업 표시
    $('.action_btn').each(function(){
        order_status = $(this).attr('order_status')
        if (order_status == '1'){
            action_text = '결제하기'
        }
        else if (order_status =='4'){
            action_text = '리뷰 작성'
        }
        else{
            action_text = $(this).attr('status_name')
        }
        $(this).text(action_text)
    })
    // 작업 버튼 클릭 이벤트
    $('.action_btn').click(function(){
        // 주문 ID 가져오기
        order_id = $(this).attr('order_id')
        // 결제 대기 상태이면 AJAX 결제 요청 전송
        if ($(this).attr('order_status') =='1'){
            payment_type = $(this).attr('payment_type')
            process_payment(order_id, payment_type)
        }
        // 리뷰 대기 상태이면 리뷰 페이지로 이동
        else if($(this).attr('order_status') == '4'){
            // 리뷰 페이지로 이동
            location.href = '/order/comment/'+order_id
        }
    })

리뷰 URL 및 뷰 클래스 추가

apps/order/url.py에 리뷰 URL을 구성합니다

from order.views import OrderReviewView

urlpatterns = [
    ...
    path('comment/<int:order_id>/', OrderReviewView.as_view(), name='review')
    ...
]

apps/order/view.py에 OrderReviewView 추가

reverse를 사용해 URL을 역방향 해석할 때, URL에 파라미터가 있는 경우 reverse의 두 번째 인자에 kwargs 파라미터를 추가하며, key는 URL 파라미터 이름입니다

class OrderReviewView(LoginRequiredMixin, View):
    '''주문 리뷰 뷰'''
    template_name = 'order/order_review.html'
    def get(self, request, order_id):
        '''리뷰 페이지 표시'''
        user = request.user
        # 데이터 검증
        if not order_id:
            return redirect(reverse('user:order', kwargs={'page_num': 1}))
        try:
            order = OrderInfo.objects.get(id=order_id, user=user)
        except OrderInfo.DoesNotExist:
            return redirect(reverse('user:order', kwargs={'page_num': 1}))
        # 주문 상품 가져오기
        order_items_list = OrderItems.objects.filter(order=order)
        for order_item in order_items_list:
            order_item.total_price = order_item.quantity * order_item.price
        # 동적 속성 할당
        order.status_text = OrderInfo.ORDER_STATUS_MAP[order.order_status]
        order.order_items_list = order_items_list
        return render(request, self.template_name, {'order': order})<br></br>

템플릿 파일 편집

{% extends 'base_user_center.html' %}
{% load static %}
{% block title %}生鲜 쇼핑몰-고객 센터{% endblock %}
{% block page_title %}고객 센터{% endblock page_title %}
{% block right %}
        <div class="right_content clearfix">
            <h3 class="common_title2">주문 리뷰</h3>
                - {{ order.create\_time }}
- 주문 번호:{{order.order\_num}}
- {{order.status\_text}}
            <form method="post">
                {% csrf_token %}
                {# 주문 ID #}
                <input type="hidden" name="order_id" value="{{order.order_id}}">
                {# 주문 상품 수 #}
                <input type="hidden" name="item_count" value="{{order.order_items_list|length}}">
                {% for order_item in order.order_items_list %}
                | - ![]({{order_item.goods.image.url }}) - {{order\_item.goods.name}}*{{order\_item.price}}/{{order\_item.goods.unit}}* - {{order\_item.quantity}} | {{order\_item.total\_price}}원 |
|---|---|
                <div class="review_section">
                    <input type="hidden" name="item_{{forloop.counter}}" value="{{order_item.goods.id}}">
                    <div class="form_group form_group2">
                        <label>리뷰 내용:</label>
                        <textarea class="review_area" name="review_{{forloop.counter}}"></textarea>
                    </div>
                </div>
                {% endfor %}
                <input type="submit" name="" value="제출" class="submit_btn">
            </form>
        </div>
{% endblock right %}

리뷰 페이지는 주문의 각 상품 아래에 리뷰를 작성할 수 있으므로, 제출 시 입력란과 해당 상품을 바인딩해야 어떤 상품의 리뷰인지 알 수 있습니다. 여기서 각 리뷰 입력란 앞에 숨겨진 input 필드를 추가했으며, name은 item_{{forloop.counter}}로 설정하고 value는 {{order_item.goods.id}}로 설정했습니다. 동시에 리뷰 입력란 textarea의 name도 review_{{ forloop.counter }}로 작성했습니다. input과 textarea의 name은 동일한 "forloop.counter"를 사용하여 바인딩되며, 상품 루프 전에도 숨겨진 input 필드를 추가하여 상품 총수를 POST로 전송합니다. 여기서 value="{{order.order_items_list|length}}"는 Django 템플릿 필터 |length를 사용한 것입니다. 다른 필터로는:{{ value|add:"2" }}、{{ value|date:"Y-m-d" }} {{ value|time:"H:i" }}、{{ value|lower }} 등이 있습니다.

리뷰 제출을 위한 POST 요청 처리

OrderReviewView를 계속 편집하여 post 메서드 추가

상품을 순회하며 루프 카운터 i를 사용하여 현재 상품 ID와 리뷰를 가져옵니다

    def post(self, request, order_id):
        '''리뷰 제출 처리'''
        user = request.user
        # 데이터 가져오기
        item_count = int(request.POST.get('item_count'))
        # 데이터 검증
        if not order_id:
            return redirect(reverse('user:order', kwargs={'page_num': 1}))
        try:
            order = OrderInfo.objects.get(id=order_id, user=user)
        except OrderInfo.DoesNotExist:
            redirect(reverse('user:order', kwargs={'page_num': 1}))

        for i in range(1, item_count+1):
            # 리뷰 내용 가져오기
            review_text = request.POST.get('review_%d' % i, '')
            # 상품 ID 가져오기
            goods_id = int(request.POST.get('item_%d' % i))
            try:
                order_item = OrderItems.objects.get(order=order, goods_id=goods_id)
            except Goods.DoesNotExist:
                continue
            order_item.comment = review_text
            order_item.save()

        order.order_status = 5  # 완료
        order.save()

        return redirect(reverse('user:order', kwargs={'page_num': 1}))

태그: 장고 주문관리 리뷰시스템 웹개발 파이썬

6월 26일 21:50에 게시됨