Django框架(十四)--購物車,全部訂單

電商項目(賣家/買家)

一、加入購物車

  • 加入購物車
    • 獲取商品id,數量,寫入購物車
  • 購物車結算
    • 首先生成訂單
    • 支付寶付款
    • 修改訂單的狀態

購物車模型

# 購物車表
class Cart(models.Model):
    goods_number = models.IntegerField(verbose_name='商品數量')
    goods_price = models.FloatField(verbose_name='商品單價')
    goods_total = models.FloatField(verbose_name='商品總價')
    goods = models.ForeignKey(to=Goods,on_delete=models.CASCADE)
    cart_user = models.ForeignKey(to=LoginUser,on_delete=models.CASCADE)

(一)添加購物車

1.列表頁添加購物車

使用前端列表中的購物車圖標,添加商品到購物車。

因爲不需要跳轉頁面,不需要刷新頁面,所以使用ajax提交,視圖返回json對象

  • 前端傳遞參數
    • 需要傳遞添加的商品id
    • 不需要傳遞商品的數量,每次點擊都是添加一個商品到購物車
  • 視圖接口接收參數
    • 商品id
    • 商品數量
      • 給默認值,因爲在前端商品列表頁的添加按鈕,每次添加都是添加一個
  • 保存數據到購物車表
    • 確定具體添加的商品
    • 確定用戶
    • 確定商品數量

視圖

# 添加購物車
def add_cart(request):
    '''
    使用post請求,完成添加購物車功能
    '''
    result = {'code':'10000','msg':''}
    if request.method=='POST':
        goods_id = request.POST.get('goods_id')
        count = int(request.POST.get('count','1'))    # 默認值1
        user_id = request.COOKIES.get('userid')
        goods = Goods.objects.get(id=goods_id)
        cart = Cart()
        cart.goods_number = count
        cart.goods_price = goods.goods_price
        cart.goods_total = goods.goods_price*count
        cart.goods = goods
        cart.cart_user = LoginUser.objects.get(id=user_id)
        cart.save()
        result['msg']='成功加入購物車'
    else:
        result['code']=10001
        result['msg']='請求方式不正確'
    return JsonResponse(result)

模板

在這裏插入圖片描述

{% block script %}
  <script>
    function add_cart(obj) {
        var goods_id = obj.id;
        url='/Buyer/add_cart/';
        send_data={
            'goods_id':goods_id ,
            'csrfmiddlewaretoken':'{{ csrf_token }}'
        };
        $.ajax(
            {
                url:url,
                type:'post',
                data:send_data,
                success:function (data) {
                    alert(data['msg'])
                },
                error:function (error) {
                    console.log(error)
                }
            }
        )
    }
  </script>
{% endblock %}

路由

在這裏插入圖片描述

2.商品詳情頁添加購物車

商品詳情頁添加購物車跟列表頁相似,可以使用同一個視圖,同一個路由

模板內的js也相似,不過就是商品詳情頁需要傳遞具體商品的數量

模板

在這裏插入圖片描述

function add_cart(obj) {
        var goods_id = obj.id;
        url='/Buyer/add_cart/';
        var count=$('#num').val();
        send_data={
            'goods_id':goods_id ,
            'count':count,
            'csrfmiddlewaretoken':'{{ csrf_token }}'
        };
        $.ajax(
            {
                url:url,
                type:'post',
                data:send_data,
                success:function (data) {
                    alert(data['msg'])
                },
                error:function (error) {
                    console.log(error)
                }
            }
        )
    }

二、購物車頁面

使用模板:cart.html

顯示登錄用戶購物車中所有的商品

(一)設置選中商品的多選框

模板

在這裏插入圖片描述
在這裏插入圖片描述

$('#boxall').click(
        function () {
            // this.checked:布爾類型,代表this指向的#boxall對象有沒有checked屬性
            if(this.checked){
                // 選中時,添加goods_check的checked屬性
                $('.goods_check').prop('checked',true)
            }
            else{
                // 不選中時,去掉goods_check的checked屬性
                $('.goods_check').prop('checked',false)
            }
        }
    );
  $('.goods_check').each(
      function () {
          $(this).click(
              function () {
                  if(!this.checked){
                      $('#boxall').prop('checked', false)
                  }
              }
          )
      }
  );

路由

在這裏插入圖片描述

視圖

@loginValid
def cart(request):
    user_id = request.COOKIES.get('userid')
    carts = Cart.objects.filter(cart_user_id=user_id,).order_by('-id')    # 晚添加的在上面
    count = carts.count()
    return render(request,'buyer/cart.html',locals())

(二)根據勾選的多選框,計算總數量,總價格

模板

function add() {
      var dic = {num:0,total:0};
      $('.goods_check').each(
          function () {
              if(this.checked){
                  // 數量
                  var num =parseInt($(this).parents('.cart_list_td').find('.num_show').val()) ;
                  // 小計
                  var total =parseFloat($(this).parents('.cart_list_td').find('.col07').text());
                  dic.num+=num;
                  dic.total+=total;
              }
          }
      );
      $('#total_mount').text(dic.total);
      $('#total_num').text(dic.num);
  }

在這裏插入圖片描述

三、提交購物車–加入訂單

購物車(多件商品),需要通過結算,先產生訂單,然後跳轉支付

(一)生成訂單

  • 能夠處理多條商品,錄入訂單
  • 接收的參數:
    • goods_id–需要從前端獲取
    • count–需要從前端獲取

模板

在這裏插入圖片描述
在這裏插入圖片描述

這樣,前端傳遞的數據格式,是這樣的:

goods_13=on     type = checkbox 有checked屬性的時候纔會傳遞
count_17=1
count_13=1
count_11=1

路由

在這裏插入圖片描述

視圖

需要處理獲取的數據,並且存入訂單狀態表和訂單詳情表

def place_order_more(request):
    data=request.GET
    userid = request.COOKIES.get('userid')
    # 通過獲取前端get請求的參數,找到goods_id和對應的數量
    request_data=[]
    for key,value in data.items():
        if key.startswith('goods'):
            goods_id = key.split('_')[1]
            count = request.GET.get('count_'+goods_id)
            request_data.append((int(goods_id),int(count)))
    if request_data:
        payorder = PayOrder()
        order_number = str(time.time()).replace('.', '')
        payorder.order_number = order_number
        payorder.order_status = 0
        payorder.order_total = 0
        order_total = 0
        total_count = 0
        payorder.order_user = LoginUser.objects.get(id=userid)
        payorder.save()
        for goods_id_one,count_one in request_data:
            goods = Goods.objects.get(id=goods_id_one)
            orderinfo = OrderInfo()
            orderinfo.order_id_id = payorder.id
            orderinfo.goods = goods
            orderinfo.goods_count = count_one
            orderinfo.goods_price = goods.goods_price
            orderinfo.goods_total_price = goods.goods_price * count_one
            orderinfo.store_id = goods.goods_store
            orderinfo.save()
            order_total+=orderinfo.goods_total_price
            total_count+=count_one

        payorder.order_total=order_total
        payorder.save()
    return render(request,'buyer/place_order.html',locals())

(二)跳轉支付頁面並修改訂單狀態

無需修改

模板

在這裏插入圖片描述

payresult.html

{% extends 'buyer/base.html' %}
{% block title %}
  支付結果
{% endblock %}
{% block content %}
  <div class="list_model">
    <h1>支付結果</h1>
    <table>
    {% for key,value in request.GET.items %}
      <tr>
        <th>{{ key }}:</th>
        <td>{{ value }}</td>
      </tr>
    {% endfor %}
    </table>
  </div>
{% endblock %}

路由

在這裏插入圖片描述

視圖

def AlipayView(request):
    order_id=request.GET.get('order_id')    # 訂單ID
    payorder=PayOrder.objects.get(id=order_id)
    # 實例化支付對象
    alipay = AliPay(
        appid='2016101300673951',
        app_notify_url=None,
        app_private_key_string=alipay_private_key_string,
        alipay_public_key_string=alipay_public_key_string,
        sign_type="RSA2",
    )
    # 實例化訂單
    order_string = alipay.api_alipay_trade_page_pay(
        subject='天天生鮮',  # 交易主題
        out_trade_no=payorder.order_number,  # 訂單號
        total_amount=str(payorder.order_total),  # 交易總金額
        return_url='http://127.0.0.1:8000/Buyer/payresult/',  # 請求支付之後及時回調的一個接口
        notify_url='http://127.0.0.1:8000/Buyer/payresult/'  # 通知地址
    )
    # 發送支付請求
    # 請求地址:支付網關+實例化訂單
    result = 'https://openapi.alipaydev.com/gateway.do?' + order_string
    return HttpResponseRedirect(result)

def payresult(request):
    order_number = request.GET.get('out_trade_no')
    payorder = PayOrder.objects.get(order_number=order_number)
    payorder.order_status=1
    payorder.save()
    return render(request,'buyer/payresult.html',locals())

三、購物車優化

不顯示已提交訂單並付款的商品

1.購物車表中增加訂單號字段,與訂單表產生聯繫

就可以使用訂單表中的訂單狀態

在這裏插入圖片描述

進行數據遷移

2.使生成訂單時,多傳遞一個參數:購物車id

爲訂單相關產品增加訂單號
在這裏插入圖片描述

修改place_order_more視圖
在這裏插入圖片描述
在這裏插入圖片描述

3.就可以通過訂單號,查看當前訂單狀態了

若訂單時已付款狀態,則不顯示在購物車當中

修改cart視圖

@loginValid
def cart(request):
    user_id = request.COOKIES.get('userid')
    carts = Cart.objects.filter(cart_user_id=user_id,).order_by('-id')    # 晚添加的在上面
    cart_list = []
    for one in carts:
        # 說明有訂單號
        if one.order_number != '0':
            payorder = PayOrder.objects.get(order_number=one.order_number)
            if payorder.order_status == 0:
                cart_list.append(one)
        else:
            cart_list.append(one)
    count = len(cart_list)
    return render(request,'buyer/cart.html',locals())

修改cart.html模板

在這裏插入圖片描述

四、用戶中心全部訂單頁

獲取用戶的全部訂單

視圖

@loginValid
def user_center_order(request):
    user_id = request.COOKIES.get('userid')
    user = LoginUser.objects.get(id=user_id)
    payorder = user.payorder_set.order_by('-order_date','order_status')

    return render(request,'buyer/user_center_order.html',locals())

路由

在這裏插入圖片描述

模板

修改模型
在這裏插入圖片描述

user_center_order.html

{% extends 'buyer/base.html' %}
{% block title %}
  全部訂單
{% endblock %}
{% block content %}
  <div class="main_con clearfix">
		<div class="left_menu_con clearfix">
			<h3>用戶中心</h3>
			<ul>
				<li><a href="/Buyer/user_center_info/">· 個人信息</a></li>
				<li><a href="/Buyer/user_center_order/" class="active">· 全部訂單</a></li>
				<li><a href="">· 收貨地址</a></li>
			</ul>
		</div>
		<div class="right_content clearfix">
				<h3 class="common_title2">全部訂單</h3>
      {% for order in payorder %}
				<ul class="order_list_th w978 clearfix">
					<li class="col01">{{ order.order_date }}</li>
					<li class="col02">{{ order.order_number }}</li>
					<li  class="col02 stress">{{ order.get_order_status_display }}</li>
				</ul>
				<table class="order_list_table w980">
					<tbody>
						<tr>
							<td width="55%">
                {% for orderinfo in order.orderinfo_set.all %}
								<ul class="order_goods_list clearfix">
									<li class="col01"><img src="/static/{{ orderinfo.goods.picture }}"></li>
									<li class="col02">{{ orderinfo.goods.goods_name }}<em>{{ orderinfo.goods_price }}/500g</em></li>
									<li class="col03">{{ orderinfo.goods_count }}</li>
									<li class="col04">{{ orderinfo.goods_total_price }}元</li>
								</ul>
                {% endfor %}
							</td>
							<td width="15%">{{ order.order_total }}元</td>
							<td width="15%">{{ order.get_order_status_display }}</td>
              {% if order.order_status == 0 %}
							<td width="15%"><a href="/Buyer/alipayview/?order_id={{ order.id }}" class="oper_btn">去付款</a></td>
              {% elif order.order_status == 1 %}
              <td width="15%"><a href="" class="oper_btn">查看訂單</a></td>
              {% endif %}
						</tr>
					</tbody>
				</table>
        {% endfor %}
				<div class="pagenation">
					<a href="#"><上一頁</a>
					<a href="#" class="active">1</a>
					<a href="#">2</a>
					<a href="#">3</a>
					<a href="#">4</a>
					<a href="#">5</a>
					<a href="#">下一頁></a>
				</div>
		</div>
	</div>
{% endblock %}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章