订单相关

class Creat(APIView):   # 创建订单
    @transaction.atomic   # 开启事务
    def post(self,request):
        param=request.data
        order_obj=OrderForm(request.data)
        host_ip=request.get_host()
        goods_list=param.get("buy_list")
        #这个的goods_list,就是用户下单的商品以及数量
        #数据格式{"2":2,"1":2}
        if order_obj.is_valid() and goods_list:
            open_id=function.check_login_key(param['token'])
            if not open_id:
                return Response({"code":200,"msg":"token不对"})
            user=models.Wxuser.objects.filter(openid=open_id).first()
            # 组织订单的信息
            order_data={"consignee_mobile":param['phone'],'consignee_name':param['name'],'wxuser_id':user.id,
                        "memo":param['remark'],"consignee_address":f"{param['province']},{param['city']},{param['county']}",
                        }
            order_data['order_id']=function.get_order_id()

            order_data['order_total']=0
            order_data['quantity']=0
            goods_list_id = list(goods_list.keys())
            #这里是所有商品的信息
            all_good_info=models.Product.objects.filter(product_id__in=goods_list_id)
            sid=transaction.savepoint()   # 创建一个保存点,当数据库出现错误时,可以返回到当前状态
            for goods in all_good_info:
                goods.product_id = str(goods.product_id)
                order_data["order_total"]+=goods.price*goods_list[goods.product_id]
                order_data['quantity']+=goods_list[goods.product_id]
                for i in range(3):
                    stock=goods.stock.quantity  # 点的时候还是在查数据库,拿到最新的数据
                    new_quantity=stock-goods_list[goods.product_id]

                    #判断库存是否够
                    if new_quantity < 1:
                        transaction.savepoint_rollback(sid)      # 在一定条件下,事务回滚到保存点
                        return Response({
                            "code": 200,
                            'msg': "库存不足"
                        })
                    buy_count=goods.buy_count+goods_list[goods.product_id]
                    res=models.Stock.objects.filter(quantity=stock,stock_id=goods.stock.stock_id).update(quantity=new_quantity)
                    if res==0:
                        if i==2:  # 多循环几次,尽量操作成功
                            transaction.savepoint_rollback(sid)
                            return Response({"code":200,"msg":"下单失败"})
                        continue
                    else:
                        break
                order_item_data = {'order_id': order_data['order_id'], 'product_id': goods.product_id, 
                                   "name": goods.name, "image": goods.image, "price": goods.price, 
                                   "nums": goods_list[goods.product_id], "brief": goods.brief}
                models.Order_items.objects.create(**order_item_data)   # 创建子订单
                models.Product.objects.filter(product_id=goods.product_id).update(buy_count=buy_count)
            models.Order.objects.create(**order_data)
            pay_methon="Wxpay"
            try:
                pay_file=importlib.import_module(f"app01.pay.{pay_methon}")
                pay_class=getattr(pay_file,pay_methon)
                order_data['ip']=host_ip.split(":")[0]
                order_data['open_id']=open_id
                data=pay_class().pay(order_data)
                transaction.savepoint_commit(sid)
                #提交一个celery任务检查订单
                function.add_task(order_data['order_id'])
                return Response({"code":0,"msg":"成功","data":data})
            except:
                transaction.savepoint_rollback(sid)
                return  Response({"code":200,"msg":"未知的支付方式"})
        else:
            return Response({"code":200,"msg":"数据错误"})



from datetime import datetime
from app01.tasks import del_order
def add_task(order_id,how_time=0):
    ctime = datetime.now()
    utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
    from datetime import timedelta
    time_delay = timedelta(seconds=900)
    # time_delay = timedelta(seconds=how_time)  # 传过来的时间去确定多久执行一次,而非固定时间,更加人性化

    task_time = utc_ctime + time_delay
    result = del_order.apply_async(args=[order_id, ], eta=task_time)
    print(result)



@task
@transaction.atomic
def del_order(order_id):
        #把他当作一个脚本,如果要用的话,我就要启动django
        BASE_DIR = os.path.dirname(os.path.dirname(__file__))  # 定位到你的django根目录
        sys.path.append(os.path.abspath(BASE_DIR))
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "py8api.settings")
        django.setup()
        from app01 import models
        #检查该订单是否被支付,
        order_data=models.Order.objects.filter(order_id=order_id,pay_status=0,status="active")
        #如果没有被支付
        if order_data:
            #获取该订单的所有子订单中的商品和商品的数量
            order_items=models.Order_items.objects.filter(order_id=order_id).values('product','nums')
            #将查出来的商品和数量做成字典:{product_id:nums}
            goods_list= {item['product']:item['nums'] for item in order_items}
            #获取所有的商品的id
            goods_list_id=list(goods_list.keys())
            #获取所有的商品
            all_goods_info = models.Product.objects.filter(product_id__in=goods_list_id)
            #开启事务
            sid = transaction.savepoint()
            #循环处理。所有的商品
            for goods in all_goods_info:
                # 如果下单成功后的库存
                for i in range(3):
                    new_quantity = goods.stock.quantity + goods_list[goods.product_id]
                    buy_count = goods.buy_count - goods_list[goods.product_id]
                    res = models.Stock.objects.filter(quantity=goods.stock.quantity, stock_id=goods.stock.stock_id).update(
                        quantity=new_quantity)
                    if res == 0:
                        if i == 2:
                            # 回滚
                            transaction.savepoint_rollback(sid)
                            #但是还要继续提交任务取消订单
                            from  app01.comment import function
                            function.add_taks(order_id)
                            return
                        continue
                    else:
                        models.Product.objects.filter(product_id=goods.product_id).update(buy_count=buy_count)
                        break
            res= models.Order.objects.filter(order_id=order_id, pay_status=0,status="active").update(status="dead")
            if res ==0 :
                #订单刚好付款了
                transaction.savepoint_rollback(sid)
            transaction.savepoint_commit(sid)
原文地址:https://www.cnblogs.com/changwenjun-666/p/11669395.html