购物车cart.html页面加form表单提交
<form method="post" action="{% url ‘order:place‘ %}"> {# 提交到/order/place页面处理 #} {% for sku in skus %} <ul class="cart_list_td clearfix"> <li class="col01"><input type="checkBox" name="sku_ids" value="{{ sku.id }}" checked></li> <li class="col02"><img src="{{ sku.image.url }}"></li> <li class="col03">{{ sku.name }}<br><em>{{ sku.price }}元/{{ sku.unite }}</em></li> <li class="col04">{{ sku.unite }}</li> <li class="col05">{{ sku.price }}元</li> <li class="col06"> <div class="num_add"> <a href="javascript:;" class="add fl">+</a> <input type="text" sku_id="{{ sku.id }}" class="num_show fl" value="{{ sku.count }}"> <a href="javascript:;" class="minus fl">-</a> </div> </li> <li class="col07">{{ sku.amount }}元</li> <li class="col08"><a href="javascript:;">删除</a></li> </ul> {% endfor %} <ul class="settlements"> {% csrf_token %} <li class="col01"><input type="checkBox" name="" checked=""></li> <li class="col02">全选</li> <li class="col03">合计(不含运费):<span>¥</span><em>{{ total_price }}</em><br>共计<b>{{ total_count }}</b>件商品</li> <li class="col04"><input type="submit" value="去结算"></li> </ul> </form>
from django.shortcuts import render,redirect from django.core.urlresolvers import reverse from django.http import JsonResponse from django.views.generic import View from user.models import Address from goods.models import GoodsSKU from orders.models import OrderInfo,OrderGoods from django_redis import get_redis_connection # 连接redis from utils.mixin import LoginrequiredMinxin # 登录验证 from datetime import datetime # Create your views here. # /order/place class OrderPlaceView(LoginrequiredMinxin,View): ‘‘‘提交订单页面显示‘‘‘ def post(self,request): ‘‘‘提交订单页面显示‘‘‘ # 获取登录的用户 user = request.user # 获取参数sku_ids sku_ids = request.POST.getlist(‘sku_ids‘) # [1,26] # 校验参数 if not sku_ids: # 跳转到购物车页面 return redirect(reverse(‘cart:show‘)) conn = get_redis_connection(‘default‘) cart_key = ‘cart_%d‘%user.id skus = [] # 保存商品的总件数和总价格 total_count = 0 total_price = 0 # 遍历sku_ids获取用户要购买的商品的信息 for sku_id in sku_ids: # 根据商品的id获取商品的信息 sku = GoodsSKU.objects.get(id=sku_id) # 获取用户所要购买的商品的数量 count = conn.hget(cart_key,sku_id) # 计算商品的小计 amount = sku.price*int(count) # 动态给sku增加属性count,保存购买商品的数量 sku.count = count # 动态给sku增加属性amount,保存购买商品的小计 sku.amount = amount # 追加 skus.append(sku) # 累加计算商品的总件数和总价格 total_count += int(count) total_price += amount # 运费:实际开发的时候,属于一个子系统 transit_price = 10 # 写死 # 实付款 total_pay = total_price + transit_price # 获取用户的收件地址 addrs = Address.objects.filter(user=user) # 组织上下文 sku_ids = ‘,‘.join(sku_ids) # [1,25]->1,25 把列表拼接成字符串形式传参 context = {‘skus‘:skus,‘total_count‘:total_count,‘total_price‘:total_price,‘transit_price‘:transit_price,‘total_pay‘:total_pay,‘addrs‘:addrs,‘sku_ids‘:sku_ids} # 使用模板 return render(request,‘place_order.html‘,context)
模板order_place.html
{% extends ‘layout/base_no_cart.html‘ %} {% load staticfiles %} {% block title %}天天生鲜-提交订单{% endblock title %} {% block page_title %}提交订单{% endblock page_title %} {% block body %} <h3 class="common_title">确认收货地址</h3> <div class="common_list_con clearfix"> <dl> <dt>寄送到:</dt> {% for addr in addrs %} <dd><input type="radio" name="addr_id" value="{{ addr.id }}" {% if addr.is_default %}checked{% endif %}>{{ addr.addr }} ({{ addr.receiver }} 收) {{ addr.phone }}</dd> {% endfor %} </dl> <a href="{% url ‘user:address‘ %}" class="edit_site">编辑收货地址</a> </div> <h3 class="common_title">支付方式</h3> <div class="common_list_con clearfix"> <div class="pay_style_con clearfix"> <input type="radio" name="pay_style" value="1" checked> <label class="cash">货到付款</label> <input type="radio" name="pay_style" value="2"> <label class="weixin">微信支付</label> <input type="radio" name="pay_style" value="3"> <label class="zhifubao"></label> <input type="radio" name="pay_style" value="4"> <label class="bank">银行卡支付</label> </div> </div> <h3 class="common_title">商品列表</h3> <div class="common_list_con clearfix"> <ul class="goods_list_th clearfix"> <li class="col01">商品名称</li> <li class="col02">商品单位</li> <li class="col03">商品价格</li> <li class="col04">数量</li> <li class="col05">小计</li> </ul> {% for sku in skus %} <ul class="goods_list_td clearfix"> <li class="col01">{{ forloop.counter }}</li> <li class="col02"><img src="{{ sku.image.url }}"></li> <li class="col03">{{ sku.name }}</li> <li class="col04">{{ sku.unite }}</li> <li class="col05">{{ sku.price }}元</li> <li class="col06">{{ sku.count }}</li> <li class="col07">{{ sku.amount }}元</li> </ul> {% endfor %} </div> <h3 class="common_title">总金额结算</h3> <div class="common_list_con clearfix"> <div class="settle_con"> <div class="total_goods_count">共<em>{{ total_count }}</em>件商品,总金额<b>{{ total_price }}元</b></div> <div class="transit">运费:<b>{{ transit_price }}元</b></div> <div class="total_pay">实付款:<b>{{ total_pay }}元</b></div> </div> </div> <div class="order_submit clearfix"> {% csrf_token %} <a href="javascript:;" sku_ids={{ sku_ids }} id="order_btn">提交订单</a> </div> {% endblock body %} {% block bottom %} <div class="popup_con"> <div class="popup"> <p>订单提交成功!</p> </div> <div class="mask"></div> </div> {% endblock bottom %} {% block bottomfiles %} <script type="text/javascript" src="{% static ‘js/jquery-1.12.4.min.js‘ %}"></script> <script type="text/javascript"> $(‘#order_btn‘).click(function() { // 获取用户选择的地址id,支付方式,要购买的商品id字符串 addr_id = $(‘input[name="addr_id"]:checked‘).val() // 获取地址 pay_method = $(‘input[name="pay_style"]:checked‘).val() // 获取支付方式 sku_ids = $(this).attr(‘sku_ids‘) // 获取商品id拼接的字符串 csrf = $(‘input[name="csrfmiddlewaretoken"]‘).val() // alert(addr_id+":"+pay_method+‘:‘+sku_ids) // 组织参数 params = {‘addr_id‘:addr_id,‘pay_method‘:pay_method,‘sku_ids‘:sku_ids,‘csrfmiddlewaretoken‘:csrf} // 发起ajax post请求,访问/order/commit,传递的参数: addr_id pay_method,sku_ids $.post(‘/order/commit‘,params,function (data) { if (data.res == 5){ // 创建成功 alert(‘创建成功‘) } else{ alert(data.errmsg) } }) {# localStorage.setItem(‘order_finish‘,2);#} {##} {# $(‘.popup_con‘).fadeIn(‘fast‘,function() {#} {##} {# setTimeout(function(){#} {# $(‘.popup_con‘).fadeOut(‘fast‘,function(){#} {# window.location.href = ‘index.html‘;#} {# }); #} {# },3000)#} {# #} {# });#} }); </script> {% endblock bottomfiles %}
# 前端传递的参数:地址id(addr_id) 支付方式(pay_method) 用户要购买的商品id字符串(sku_ids) # MysqL事务: 一组sql操作,要么都成功,要么都失败 # 高并发:秒杀 # 支付宝支付 class OrderCommitView(View): ‘‘‘订单创建‘‘‘ def post(self,request): ‘‘‘订单创建‘‘‘ # 判断用户是否登录 user = request.user if not user.is_authenticated(): # 用户未登录 return JsonResponse({‘res‘:0,‘errmsg‘:‘用户未登录‘}) # 接收参数 addr_id = request.POST.get(‘addr_id‘) pay_method = request.POST.get(‘pay_method‘) sku_ids = request.POST.get(‘sku_ids‘) # 1,3 # 校验参数 if not all([addr_id,pay_method,sku_ids]): return JsonResponse({‘res‘:1,‘errmsg‘:‘参数不完整‘}) # 校验支付方式 if pay_method not in OrderInfo.PAY_METHODS.keys(): # 需要在orders/model.py中添加PAY_METHODS字典 return JsonResponse({‘res‘:2,‘errmsg‘:‘非法的支付方式‘}) # 校验地址 try: addr = Address.objects.get(id=addr_id) except Address.DoesNotExist: # 地址不存在 return JsonResponse({‘res‘:3,‘errmsg‘:‘地址非法‘}) # todo: 创建订单核心业务 # 组织参数 # 订单id: 20171122181630+用户id order_id = datetime.now().strftime(‘%Y%m%d%H%M%S‘)+str(user.id) # 运费 transit_price = 10 # 总数目和总金额 total_count = 0 total_price = 0 # todo: 向df_order_info表中添加一条记录 order = OrderInfo.objects.create(order_id=order_id,user=user,addr=addr,pay_method=pay_method,total_count=total_count,total_price=total_price,transit_price=transit_price) # todo: 用户的订单中有几个商品,需要向df_order_goods表中加入几条记录 conn = get_redis_connection(‘default‘) cart_key = ‘cart_%d‘%user.id sku_ids = sku_ids.split(‘,‘) for sku_id in sku_ids: # 获取商品的信息 try: sku = GoodsSKU.objects.get(id=sku_id) except: # 商品不存在 return JsonResponse({‘res‘:4,‘errmsg‘:‘商品不存在‘}) # 从redis中获取用户所要购买的商品的数量 count = conn.hget(cart_key,sku_id) # todo: 向df_order_goods表中添加一条记录 OrderGoods.objects.create(order=order,sku=sku,count=count,price=sku.price) # todo: 更新商品的库存和销量 sku.stock -= int(count) sku.sales += int(count) sku.save() # todo: 累加计算订单商品的总数量和总价格 amount = sku.price*int(count) total_count += int(count) total_price += amount # todo: 更新订单信息表中的商品的总数量和总价格 order.total_count = total_count order.total_price = total_price order.save() # todo: 清除用户购物车中对应的记录 conn.hdel(cart_key,*sku_ids) # 返回应答 return JsonResponse({‘res‘:5,‘message‘:‘创建成功‘})
此时需要在orders/models.py中OrderInfo方法中添加字典
class OrderInfo(BaseModel): ‘‘‘订单模型类‘‘‘ PAY_METHODS = { ‘1‘: "货到付款",‘2‘: "微信支付",‘3‘: "支付宝",‘4‘: ‘银联支付‘ } PAY_METHODS_ENUM = { "CASH": 1,"ALIPAY": 2 } ORDER_STATUS_ENUM = { "UNPAID": 1,"UNSEND": 2,"UNRECEIVED": 3,"UNCOMMENT": 4,"FINISHED": 5 }