给订单加乐观锁和事务(并发处理)
from rest_framework.views import APIView from rest_framework.response import Response from app01 import models from django.core.cache import cache from django import forms from app01.comment import function from django.db import transaction class OrderForm(forms.Form): phone = forms.CharField( error_messages={ "required": "手机号不能为空" }, # 调用Form组件中的验证器来校验手机号 # validators=[RegexValidator(r'1[1-9][0-9]{9}', '手机号格式不正确')], ) token = forms.CharField( error_messages={ "required": "token不能为空" }) province=forms.CharField( error_messages={ "required": "省份不能为空" }) city = forms.CharField(error_messages={ "required": "城市不能为空" }) county = forms.CharField(error_messages={ "required": "县/区不能为空" }) address = forms.CharField(error_messages={ "required": "详细地址不能为空" }) name = forms.CharField(error_messages={ "required": "姓名不能为空" }) class Create(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") if order_obj.is_valid() and goods_list: data=cache.get(param.get("token")) if not data: return Response({ "code": 200, "msg": "token错误", }) openid=data.split("&")[0] user_info=models.Wxuser.objects.filter(openid=openid).first() order_id = function.get_order_id() order_data = {"order_id":order_id, "wxuser":user_info, "memo":param.get("remark"), "consignee_name":param.get("name"), "consignee_area":f"{param.get('province')}-{param.get('city')}-{param.get('county')}" , "consignee_address":param.get('address'), "consignee_mobile":param.get('phone'), } goods_list_id=list(goods_list.keys()) all_goods=models.Product.objects.filter(pk__in=goods_list_id) order_total=0 sid=transaction.savepoint() for goods in all_goods: goods.pk=str(goods.pk) order_total+=goods.price*goods_list[goods.pk] for i in range(3): stock=goods.stock.quantity new_stock=stock-goods_list[goods.pk] if not new_stock<0 : res=models.Stock.objects.filter(pk=goods.stock.pk,quantity=stock).update(quantity=new_stock) if res == 0: if i == 2: transaction.savepoint_rollback(sid) return Response({"code": 200, "msg": "下单失败"}) continue else: break else: transaction.savepoint_rollback(sid) return Response({ "code": 200, "msg": "库存不足", }) new_buy_count=goods.buy_count+goods_list[goods.pk] models.Product.objects.filter(pk=goods.pk).update(buy_count=new_buy_count) order_item_data={ "order_id":order_id, "product_id":goods.pk, "name":goods.name, "image":goods.image, "price":goods.price, "amount":goods.weight, "nums":goods_list[goods.pk], "brief":goods.intor } models.Order_items.objects.create(**order_item_data) order_data['order_total']=order_total models.Order.objects.create(**order_data) transaction.savepoint_commit(sid) #添加celery任务,判断两小时后要不要取消订单 function.add_task(order_id) paytype="Alipay" # try: import importlib pay_file=importlib.import_module(f"app01.pay.{paytype}") pay_class=getattr(pay_file,paytype) pay_class().pay(order_data) # except: # return return Response({ "code": 200, "msg": "ok", }) else: return Response({ "code": 200, "msg": "缺少参数", })
celery自动取消订单
from celery import task import os,sys import django from django.db import transaction @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=False).first() if order_data: order_item_data=models.Order_items.objects.filter(order_id=order_id).values_list("product_id","nums") product_list={item[0]:item[1] for item in order_item_data} product_all_id=list(product_list.keys()) product_all_obj=models.Product.objects.filter(pk__in=product_all_id) sid=transaction.savepoint() # print("product_all_id",product_all_id) for goods in product_all_obj: for i in range(3): stock=goods.stock.quantity # print("stock",stock) new_stock=stock+product_list[goods.pk] new_buy_count=goods.buy_count-product_list[goods.pk] # import time # print("我开始睡了") # time.sleep(20) res=models.Stock.objects.filter(pk=goods.stock_id,quantity=stock).update(quantity=new_stock) if not res: # print("我到这里了") if i==2: transaction.savepoint_rollback(sid) from app01.comment import function function.add_task(order_id,5) return continue else: models.Product.objects.filter(pk=goods.pk).update(buy_count=new_buy_count) break res=models.Order.objects.filter(order_id=order_id,pay_status=False).update(status="dead") # print("res1",res) if res: transaction.savepoint_commit(sid) else: transaction.savepoint_rollback(sid)
多种支付方式类的设计
回调: