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)

模板

Django框架(十四)--购物车,全部订单_第1张图片

{% 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 %}

路由

Django框架(十四)--购物车,全部订单_第2张图片

2.商品详情页添加购物车

商品详情页添加购物车跟列表页相似,可以使用同一个视图,同一个路由

模板内的js也相似,不过就是商品详情页需要传递具体商品的数量

模板

Django框架(十四)--购物车,全部订单_第3张图片

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

显示登录用户购物车中所有的商品

(一)设置选中商品的多选框

模板

Django框架(十四)--购物车,全部订单_第4张图片
Django框架(十四)--购物车,全部订单_第5张图片

$('#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)
                  }
              }
          )
      }
  );

路由

Django框架(十四)--购物车,全部订单_第6张图片

视图

@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);
  }

Django框架(十四)--购物车,全部订单_第7张图片

三、提交购物车–加入订单

购物车(多件商品),需要通过结算,先产生订单,然后跳转支付

(一)生成订单

  • 能够处理多条商品,录入订单
  • 接收的参数:
    • goods_id–需要从前端获取
    • count–需要从前端获取

模板

Django框架(十四)--购物车,全部订单_第8张图片
Django框架(十四)--购物车,全部订单_第9张图片

这样,前端传递的数据格式,是这样的:

goods_13=on     type = checkbox 有checked属性的时候才会传递
count_17=1
count_13=1
count_11=1

路由

Django框架(十四)--购物车,全部订单_第10张图片

视图

需要处理获取的数据,并且存入订单状态表和订单详情表

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())

(二)跳转支付页面并修改订单状态

无需修改

模板

Django框架(十四)--购物车,全部订单_第11张图片

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 %}

路由

Django框架(十四)--购物车,全部订单_第12张图片

视图

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.购物车表中增加订单号字段,与订单表产生联系

就可以使用订单表中的订单状态

Django框架(十四)--购物车,全部订单_第13张图片

进行数据迁移

2.使生成订单时,多传递一个参数:购物车id

为订单相关产品增加订单号
Django框架(十四)--购物车,全部订单_第14张图片

修改place_order_more视图
Django框架(十四)--购物车,全部订单_第15张图片
Django框架(十四)--购物车,全部订单_第16张图片

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模板

Django框架(十四)--购物车,全部订单_第17张图片

四、用户中心全部订单页

获取用户的全部订单

视图

@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())

路由

Django框架(十四)--购物车,全部订单_第18张图片

模板

修改模型
Django框架(十四)--购物车,全部订单_第19张图片

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 }}/500gem>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">1a>
					<a href="#">2a>
					<a href="#">3a>
					<a href="#">4a>
					<a href="#">5a>
					<a href="#">下一页>a>
				div>
		div>
	div>
{% endblock %}

你可能感兴趣的:(Django框架)