zoukankan      html  css  js  c++  java
  • 11_8,事务的隔离级别celery定时订单与项目整合。

    一。事务的隔离级别。

      mysql的默认数据库级别是可重复读,一般的应用使用的是读已提交

      http://www.zsythink.net/archives/1233/

      1. Read UnCommitted(读未提交)

      最低的隔离级别。一个事务可以读取另一个事务并未提交的更新结果。

      2. Read Committed(读提交)

      大部分数据库采用的默认隔离级别。一个事务的更新操作结果只有在该事务提交之后,另一个事务才可以的读取到同一笔数据更新后的结果。

      3. Repeatable Read(重复读)

      mysql的默认级别。整个事务过程中,对同一笔数据的读取结果是相同的,不管其他事务是否在对共享数据进行更新,也不管更新提交与否。

      4. Serializable(序列化)

      最高隔离级别。所有事务操作依次顺序执行。注意这会导致并发度下降,性能最差。通常会用其他并发级别加上相应的并发锁机制来取代它。

      1.脏读。

      当两个事务对数据进行操作时,事务A读取了一些数据之后,对其进行修改,但是还未提交,事务b对该数据进行读取的时候读取的是事务a修改后的数据,这个数据就是一个脏数据,如果数据a对该数据进行回滚,就会报错。

      2.不可重复读

      当事务A对一些数据进行读取的时候,事务B也对该数据进行了读取,并修改,当事务A再次对其进行读取的时候,就会发现数据不对,就是不可重复读。即数据不重复。

      3。幻读。

      在重复读的隔离级别下,数据是不能被修改的,但是可以被提交,所以当事务A对影响行数据进行读取的时候,事务b添加了一项数据,事务A再次读取的时候就会发现多了一条数据,就像出现幻觉一样。

      处理方法:

      1.悲观锁。

      当事务处理数据的时候。默认所有的数据会被其他数据操作,所以加上锁,不开放任何权限(包括查的权限),保证所有数据都处理完再开放锁。

      2。乐观锁,

      当处理事务的时候,默认所有的数据不会被其他数据,再提交数据之前再进行判断库中的数据是否和一开始读的数据相同(需要再可重复读的级别下,再事务过程中,保证识别到其他操作的提交数据)。

      在处理数据时,后提交的操作会时最终的数据。

    二。celery

      当订单提交完毕之后,用户不会马上支付,就会调用celery分配异步任务,将该任务延时一定时间,将其回滚到一开始的状态。

    项目详情。

    comment

    def get_level(data):
        data_list=[]
        for item in data:
            if item['parent_id']==0:
                item['level']=0
            else:
                item['level']=1
            data_list.append(item)
        return data_list
    
    
    data=[
        {"cat_id":1,"name":"北京","parent_id":0},
        {"cat_id":2,"name":"上海","parent_id":0},
        {"cat_id":3,"name":"沙河","parent_id":1},
        {"cat_id":4,"name":"sb镇","parent_id":3},
        {"cat_id":5,"name":"昌平","parent_id":1},
        {"cat_id":6,"name":"青浦","parent_id":2},
    ]
    
    def get_tree(data):
        lists=[]
        tree={}
        for i in data:
            tree[i['cat_id']]=i
        for item in data:
            if not item['parent_id']:
                lists.append(tree[item['cat_id']])
            else:
                if "children" not in tree[item['parent_id']]:
                    tree[item['parent_id']]['children']=[]
                tree[item['parent_id']]['children'].append(tree[item['cat_id']])
        return lists
    
    print(get_tree(data))
    
    
    
    
    
    res=[]
    def get_son(data,level=0,parent_id=0,is_clear=True):
        if is_clear:
            res.clear()
        for item in data:
            if item['parent_id']==parent_id:
                item['level']=level
                res.append(item)
                get_son(data,level=level+1,parent_id=item['cat_id'],is_clear=False)
        return res
    
    # print(get_son(data))
    # son=get_son(data)
    # for i in son:
    #     print("-"*i['level']+i['name'])
    # 1北京 0
    #     2-海淀1
    #         4--sb镇2
    #     -昌平
    # 3 上海 0
    #     -青浦
    #     --徐泾镇
    #     -闵行
    res_id=[]
    def get_son_id(data,parent_id=0,is_clear=True):
        if is_clear:
            res_id.clear()
            if parent_id :
                res_id.append(parent_id)
    
        for item in data:
            if item['parent_id']==parent_id:
                res_id.append(item['cat_id'])
                get_son_id(data,parent_id=item['cat_id'],is_clear=False)
        return res_id
    
    # print(get_son_id(data,1))
    
    import time ,random
    def get_order_id():
        st="012345679qwertyui"
        order_id=str(time.strftime("%Y%m%d%h%M%S"))+"".join(random.sample(st,5))
        return order_id
    
    from datetime import datetime
    
    def add_task(order_id,seconds=5):
        from pro_celery.celery import del_order
        ctime = datetime.now()
        utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
        from datetime import timedelta
        time_delay = timedelta(seconds=seconds)
        task_time = utc_ctime + time_delay
        result = del_order.apply_async(args=[order_id, ], eta=task_time)
    func.py

    my_ser

    from  rest_framework import serializers
    from app01 import  models
    class Banner_ser(serializers.ModelSerializer):
        image_url=serializers.ImageField(source="image.image_url")
        product_id=serializers.IntegerField(source="product.product_id")
        class Meta:
            model=models.Banner
            fields="__all__"
    Banner_ser
    from  rest_framework import serializers
    from app01 import  models
    class Category_ser(serializers.ModelSerializer):
        image_url=serializers.ImageField(source="image.image_url")
        parent_id=serializers.SerializerMethodField()
        def get_parent_id(self,obj):
            if obj.parent_id is None:
                return 0
            else:
                return  obj.parent_id
    
        class Meta:
            model=models.Category
            fields="__all__"
    Category_ser
    from  rest_framework import serializers
    from app01 import  models
    class Goods_ser(serializers.ModelSerializer):
        image_url=serializers.ImageField(source="image.image_url")
        stock=serializers.IntegerField(source="stock.quantity")
        class Meta:
            model=models.Product
            fields="__all__"
    Goods_ser

    Pay

    import time
    from app01.wx import settings
    class Wxpay:
        def pay(self,order_data):
            self.order_id = order_data["order_id"]
            self.open_id = order_data['open_id']
            self.ip = order_data['ip']
            data_body = self.get_body_data()
            import requests
            url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
            response = requests.post(url, data_body.encode("utf-8"), headers={'content-type': "application/xml"})
            res_dict = self.xml_to_dic(response.content)
            timeStamp = str(int(time.time()))
            paySign = self.get_pay_sign(res_dict, timeStamp)
    
            data_dic = {
                'timeStamp': timeStamp,
                'nonceStr': res_dict['nonce_str'],
                'package': f"prepay_id={res_dict['prepay_id']}",
                'signType': 'MD5',
                "paySign": paySign,
            }
    
            return data_dic
    
        def get_pay_sign(self, res_dict, timeStamp):
            data_dic = {
                'appId': res_dict['appid'],
                'timeStamp': timeStamp,
                'nonceStr': res_dict['nonce_str'],
                'package': f"prepay_id={res_dict['prepay_id']}",
                "signType": "MD5"
            }
            sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)])
            sign_str = f"{sign_str}&key={settings.pay_apikey}"
            import hashlib
            md5 = hashlib.md5()
            md5.update(sign_str.encode("utf-8"))
            sign = md5.hexdigest()
            return sign.upper()
    
        def xml_to_dic(self, xml_data):
            import xml.etree.ElementTree as ET
            '''
            xml to dict
            :param xml_data:
            :return:
            '''
            xml_dict = {}
            root = ET.fromstring(xml_data)
            for child in root:
                xml_dict[child.tag] = child.text
            return xml_dict
    
        def get_random(self):
            import random
            data = "123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP"
            nonce_str = "".join(random.sample(data, 30))
            return nonce_str
    
    
    
        def get_sign(self):
            data_dic = {
                "nonce_str": self.nonce_str,
                "out_trade_no": self.out_trade_no,
                "spbill_create_ip": self.spbill_create_ip,
                "notify_url": self.notify_url,
                "openid": self.open_id,
                "body": self.body,
                "trade_type": "JSAPI",
                "appid": self.appid,
                "total_fee": "1",
                "mch_id": self.mch_id
            }
    
            sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)])
            sign_str = f"{sign_str}&key={settings.pay_apikey}"
            import hashlib
            md5 = hashlib.md5()
            md5.update(sign_str.encode("utf-8"))
            sign = md5.hexdigest()
            return sign.upper()
    
        def get_body_data(self):
            self.appid = settings.AppId
            # openid=self.open_id
            self.mch_id = str(settings.pay_mchid)
            self.nonce_str = self.get_random()
            self.out_trade_no = self.order_id
            self.spbill_create_ip = self.ip
            self.notify_url = "https://www.test.com"
            self.body = "lzx"
            self.sign = self.get_sign()
            body_data = f"""
               <xml>
                   <appid>{self.appid}</appid>
                   <mch_id>{self.mch_id}</mch_id>
                   <nonce_str>{self.nonce_str}</nonce_str>
                   <sign>{self.sign}</sign>
                   <body>{self.body}</body>
                   <out_trade_no>{self.out_trade_no}</out_trade_no>
                   <total_fee>1</total_fee>
                   <spbill_create_ip>{ self.spbill_create_ip}</spbill_create_ip>
                   <notify_url>{self.notify_url}</notify_url>
                   <openid>{self.open_id}</openid>
                   <trade_type>JSAPI</trade_type> 
               </xml>"""
            return body_data
    Wxpay

    views

    from rest_framework.views import APIView
    from rest_framework.response import  Response
    from  app01 import models
    from app01.my_ser import Banner_ser
    
    
    class List(APIView):
        def post(self,request):
            data = models.Banner.objects.filter(is_show=True).order_by("-w_order")
            data = Banner_ser.Banner_ser(instance=data,many=True,context={"request":request}).data
            return Response({
                "code":200,
                "msg":"ok",
                "data":data
            })
    Banner
    from rest_framework.views import APIView
    from rest_framework.response import  Response
    from  app01 import models
    from app01.my_ser import Category_ser
    from app01.comment import func
    class All(APIView):
        def post(self,request):
            data=models.Category.objects.filter(is_show=True)
            data=Category_ser.Category_ser(instance=data,many=True,context={"request":request}).data
            data=func.get_son(data)
            return Response({
                "code":200,
                "msg":"ok",
                "data":data
            })
    Category
    from rest_framework.views import APIView
    from rest_framework.response import  Response
    from app01.my_ser import Goods_ser
    from  app01 import models
    from app01.my_ser import Category_ser,Goods_ser
    from app01.comment import func
    class HotGoods(APIView):
        def post(self,request):
            data=models.Product.objects.filter(disabled=True).order_by("-buy_count","-w_order")
            data=Goods_ser.Goods_ser(instance=data,many=True,context={"request":request}).data
            return  Response({"code":200,"msg":"ok","data":data})
    
    class List(APIView):
        def post(self,request):
            param=request.data
            if param.get('category_id'):
                data=models.Category.objects.filter(is_show=True)
                data=Category_ser.Category_ser(instance=data,many=True,context={"request":request}).data
                all_id=func.get_son_id(data,param['category_id'])
                data=models.Product.objects.filter(disabled=True,cat_id__in=all_id).order_by("-w_order")
                data = Goods_ser.Goods_ser(instance=data, many=True, context={"request": request}).data
                return Response({"code": 200, "msg": "ok", "data": data})
            else:
                return Response({"code": 201, "msg":"缺少参数" })
    
    class Detail(APIView):
        def post(self,request):
            param=request.data
            if param.get("id"):
                data = models.Product.objects.filter(disabled=True,product_id=param.get("id")).first()
                if data:
                    data = Goods_ser.Goods_ser(instance=data, many=False, context={"request": request}).data
                    print(data)
                    return Response({"code": 200, "msg": "ok", "data": data})
                else:
                    return Response({"code": 201, "msg": "没有该商品"})
    Goods
    import importlib
    
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from django.core.cache import cache
    from app01 import models
    from app01.comment import func
    import hashlib, time
    from django.db import transaction
    
    from django import forms
    
    
    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 Creat(APIView):
        @transaction.atomic
        def post(self, request):
            param = request.data
            form_obj = OrderForm(param)
            if form_obj.is_valid() and param['buy_list']:
                if request.META.get("HTTP_X_FORWARDED_FOR"):
                    host_ip = request.META["HTTP_X_FROWARDED_FOR"]
                else:
                    host_ip = request.META["REMOTE_ADDR"]
                user_cache = cache.get(param['token'])
                if user_cache:
                    openid = user_cache.split("&")[0]
                    user_data = models.Wxuser.objects.filter(openid=openid).first()
                    order_data = {"consignee_mobile": param['phone'],
                                  'consignee_name': param['name'],
                                  'wxuser_id': user_data.id,
                                  "memo": param['remark'],
                                  "consignee_area": f"{param['province']},{param['city']},{param['county']}",
                                  "consignee_address": param['address'],
                                  }
                    buy_list = param['buy_list']
                    goods_key = list(buy_list.keys())
                    all_product = models.Product.objects.filter(product_id__in=goods_key)
                    order_data['order_id'] = func.get_order_id()
                    order_data['order_total'] = 0
                    order_data['quantity'] = 0
                    sid = transaction.savepoint()
                    for product in all_product:
                        product.product_id = str(product.product_id)
                        order_data['order_total'] += product.price * buy_list[product.product_id]
                        order_data['quantity'] += buy_list[product.product_id]
                        # 创建子订单
                        for i in range(3):
                            stock = product.stock.quantity
                            new_stock = stock - buy_list[product.product_id]
                            if new_stock < 0:
                                transaction.rollback(sid)
                                return Response({"code": 203, "msg": f"{product.name}库存不足"})
                            res = models.Stock.objects.filter(quantity=stock, stock_id=product.stock.stock_id).update(
                                quantity=new_stock)
                            if not res:
                                if i == 2:
                                    transaction.rollback(sid)
                                    return Response({"code": 203, "msg": f"创建订单失败"})
                                else:
                                    continue
                            else:
                                break
                        new_buy_count = product.buy_count + buy_list[product.product_id]
                        models.Product.objects.filter(product_id=product.product_id).update(buy_count=new_buy_count)
                        order_item_data = {'order_id': order_data['order_id'], 'product_id': product.product_id, 
                                           "name": product.name, "image": product.image, "price": product.price, 
                                           "nums": buy_list[product.product_id], "brief": product.brief}
                        models.Order_items.objects.create(**order_item_data)
    
                        # models.Order_items.objects.create(**order_item_data)
                    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['open_id'] = openid
                        order_data['ip'] = host_ip
                        data = pay_class().pay(order_data)
                    except:
                        transaction.savepoint_rollback(sid)
                        return Response({"code": 202, "msg": "未知的支付方式"})
                    transaction.savepoint_commit(sid)
                    func.add_task(order_data['order_id'])
                    return Response({"code": 200, "msg":"ok","data":data})
                else:
                    return Response({"code": 202, "msg": "token已过期"})
            else:
                return Response({"code": 201, "msg": "缺少参数"})
    
    
    class Notity(APIView):
        def post(self,request,paymethon):
            pay_file = importlib.import_module(f"app01.Pay.{paymethon}")
            pay_class = getattr(pay_file, paymethon)
            data=pay_class().notity(request.data)
            if data['status']=="success":
                models.Order.objects.filter(order_id=data['order']).updata(pay_status=1)
    Order
    from rest_framework.views import APIView
    from rest_framework.response import  Response
    from django.core.cache import cache
    from  app01 import models
    import hashlib,time
    from app01.wx import wx_Login
    class Login(APIView):
        def post(self,request):
            param=request.data
            if param.get("code"):
                data=wx_Login.login(param.get("code"))
                if data:
                    val=data['openid']+"&"+data["session_key"]
                    key=str(int(time.time()))+data['openid']
                    md5=hashlib.md5()
                    md5.update(key.encode("utf-8"))
                    key=md5.hexdigest()
                    cache.set(key,val)
                    has_user=models.Wxuser.objects.filter(openid=data['openid']).first()
                    if not has_user:
                        models.Wxuser.objects.create(openid=data['openid'])
                    return  Response({"code":200,"msg":"ok",'data':{"login_key":key}})
    
                else:
                    return Response({"code":200,"msg":"code错误"})
            else:
                return Response({"code": 200, "msg": "缺少参数"})
    User

    wx

    import xadmin
    from xadmin import views
    from app01 import models
    
    
    class BaseSetting(object):
        """xadmin的基本配置"""
        enable_themes = True  # 开启主题切换功能
        use_bootswatch = True
    
    xadmin.site.register(views.BaseAdminView, BaseSetting)
    
    class GlobalSettings(object):
        """xadmin的全局配置"""
        site_title = "商城后台"  # 设置站点标题
        site_footer = "饼哥有限公司"  # 设置站点的页脚
        menu_style = "accordion"  # 设置菜单折叠
    
    xadmin.site.register(views.CommAdminView, GlobalSettings)
    
    
    xadmin.site.register(models.Order_items)
    xadmin.site.register(models.Product)
    xadmin.site.register(models.Order)
    xadmin.site.register(models.Category)
    xadmin.site.register(models.Stock)
    xadmin.site.register(models.Images)
    xadmin.site.register(models.Wxuser)
    
    xadmin.site.register(models.Banner)
    adminx
    from django.db import models
    
    # Create your models here.
    '''
    #banner
    id  
    image_url
    product_id
    is_show
    w_order
    create_time
    update_time
    
    
    #销量最高的排前面,销量一样,权重大的在前面
    #product_id
    id 
    name
    price
    intor
    buy_count
    w_order (越大越前)
    detail
    image_url
    scort #库存
    is_show
    catory_id
    create_time
    update_time
    
    #scort库存
    id
    name
    num
    create_time
    update_time
    
    #category_id
    id
    cate_name
    image_url
    parent_id
    create_time
    update_time
    
    #imgae
    id
    imgae_url
    name
    create_time
    update_time
    
    #订单
    order_id
    商品总数量
    总价格
    收货地址
    用户id
    订单状态(是否取消)
    收货人电话
    收人姓名
    支付
    create_time
    update_time
    
    
    order_item
    id
    order_id
    商品id
    商品价格
    num
    image_url
    create_time
    update_time
    
    '''
    
    
    
    # Create your models here.
    class Wxuser(models.Model):
        id = models.AutoField(primary_key=True)
        openid=models.CharField(max_length=255)
        name = models.CharField(max_length=50)
        avatar = models.CharField(max_length=200)
        language = models.CharField(max_length=50)
        province = models.CharField(max_length=50)
        city = models.CharField(max_length=50)
        country = models.CharField(max_length=50)
        gender = models.CharField(max_length=50),
        creat_time = models.DateTimeField(auto_now_add=True)
        update_time = models.DateTimeField(auto_now=True)
        def __str__(self):
            return self.openid
    
    class Category(models.Model):
        cat_id=models.AutoField(primary_key=True)
        category_name=models.CharField(max_length=50)
        parent=models.ForeignKey(to='Category', to_field='cat_id', related_name="Category", on_delete=models.CASCADE, db_constraint=False,blank=True,null=True)
        p_order=models.IntegerField(default=0)
        is_show =models.BooleanField(default=1)
        image = models.OneToOneField(to='Images', to_field='image_id', on_delete=models.CASCADE, db_constraint=False,null=True)
        creat_time = models.DateTimeField(auto_now_add=True)
        update_time = models.DateTimeField(auto_now=True)
        def __str__(self):
            return self.category_name
    
    
    
    class Images(models.Model):
        image_id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=30,default="0")
        image_url=models.ImageField(upload_to="")
        creat_time = models.DateTimeField(auto_now_add=True)
        update_time = models.DateTimeField(auto_now=True)
        def __str__(self):
            return self.name
    
    class Product(models.Model):
        product_id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=200)
        price=models.DecimalField(max_digits=10, decimal_places=2)
        weight=models.IntegerField(default=0)
        cat = models.ForeignKey(to="Category", to_field="cat_id", related_name="Product", db_constraint=False, on_delete=models.CASCADE)
        intor = models.TextField(max_length=250)#详细介绍
        brief = models.TextField(max_length=250)#商品简介
        image=models.OneToOneField(to='Images',to_field='image_id',on_delete=models.CASCADE,db_constraint=False)
        stock = models.OneToOneField(to="Stock", to_field="stock_id", db_constraint=False, on_delete=models.CASCADE)
        buy_count=models.IntegerField(default=0)#购买量
        disabled = models.BooleanField(default=1)#是否显示
        w_order=models.IntegerField(default=0)#权重
        creat_time = models.DateTimeField(auto_now_add=True)
        update_time = models.DateTimeField(auto_now=True)
        def __str__(self):
            return self.name
    
    
    
    class Order(models.Model):
        order_id = models.CharField(max_length=50, unique=True, primary_key=True)
        status_choices = (("active", '活动订单'), ("dead", '作废订单'), ("finish", '已完成订单'))
        status = models.CharField(choices=status_choices, default="active", max_length=50)
        pay_status_choices = ((0, '未付款'), (1, '已付款'))
        pay_status = models.SmallIntegerField(choices=pay_status_choices, default=0)
        payed = models.DecimalField(max_digits=10, decimal_places=2,default=0)
        order_total = models.DecimalField(max_digits=10, decimal_places=2,default=0)
        ship_status_choices = ((0, '未发货'), (1, '已发货'))
        pay_app = models.CharField(max_length=100)
        wxuser = models.ForeignKey(to="Wxuser", to_field="id", related_name="Order", db_constraint=False,on_delete=models.CASCADE)
        quantity = models.IntegerField(default=0)
        memo = models.CharField(max_length=200, default=0)
        consignee_name = models.CharField(max_length=200, default=0)
        consignee_area = models.CharField(max_length=200, default=0)
        consignee_address = models.CharField(max_length=200, default=0)
        consignee_zip = models.CharField(max_length=200, default=0)
        consignee_mobile = models.CharField(max_length=200,default=0)
        creat_time = models.DateTimeField(auto_now_add=True)
        update_time = models.DateTimeField(auto_now=True)
        def __str__(self):
            return self.order_id
    
    class Order_items(models.Model):
        item_id = models.AutoField(primary_key=True)
        order= models.ForeignKey(to="Order", to_field="order_id", related_name="Order_items", db_constraint=False,on_delete=models.CASCADE)
        product=models.ForeignKey(to="Product", to_field="product_id", related_name="Order_items", db_constraint=False,on_delete=models.CASCADE,null=True)
        name = models.CharField(max_length=200)
        image = models.ForeignKey(to='Images', to_field='image_id',related_name="Order_items", on_delete=models.CASCADE,db_constraint=False)
        price = models.DecimalField(max_digits=10, decimal_places=2,default=0)
        amount=models.DecimalField(max_digits=10, decimal_places=2,default=0)
        nums=models.IntegerField()
        send_nums=models.IntegerField(null=True)
        brief=models.CharField(max_length=200)
        creat_time = models.DateTimeField(auto_now_add=True)
        update_time = models.DateTimeField(auto_now=True)
    
    class Stock(models.Model):
        stock_id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=100)
        quantity=models.IntegerField(default=0)#库存量
        creat_time = models.DateTimeField(auto_now_add=True)
        update_time = models.DateTimeField(auto_now=True)
        def __str__(self):
            return self.name
    
    class Banner(models.Model):
        product = models.OneToOneField(to="Product", to_field="product_id", db_constraint=False, on_delete=models.CASCADE)
        w_order = models.IntegerField(default=0)  # 权重
        image = models.OneToOneField(to='Images', to_field='image_id', on_delete=models.CASCADE, db_constraint=False)
        is_show =models.BooleanField(default=1)
        creat_time = models.DateTimeField(auto_now_add=True)
        update_time = models.DateTimeField(auto_now=True)
        def __str__(self):
            return self.product.name
    models

    pro_celery

    import celery
    import time
    # broker='redis://127.0.0.1:6379/2' 不加密码
    backend='redis://127.0.0.1:6379/1'
    broker='redis://127.0.0.1:6379/2'
    cel=celery.Celery('test',backend=backend,broker=broker)
    
    
    import os, sys
    import django
    BASE_DIR = os.path.dirname(os.path.dirname(__file__))  # 定位到你的django根目录
    # sys.path.append(os.path.join(BASE_DIR, "app01"))
    sys.path.append(os.path.abspath(BASE_DIR))
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wxshop.settings")
    django.setup()
    from django.db import transaction
    
    
    @cel.task
    @transaction.atomic
    def del_order(order_id):
        '''
        1 拿订单查询,订单号,是否支付,活跃
        2 判断data是否有
    
        :param order_id:
        :return:
        '''
        from app01 import models
        data=models.Order.objects.filter(order_id=order_id,pay_status=0,status="active").first()
        if  data:
            item_data=models.Order_items.objects.filter(order_id=order_id).values("product","nums")
            # [{product:1,nums:3}]
            # {1:3,2:1}
            all_product_dict = { k['product']:k['nums'] for k in item_data}
            all_product_id =list(all_product_dict.keys())
            products_all=models.Product.objects.filter(product_id__in=all_product_id)
            sid=transaction.savepoint()
    
            for product in  products_all:
                for i in range(3):
                    stock=product.stock.quantity
                    new_stock=stock+all_product_dict[product.product_id]
                    new_buy_count=product.buy_count-all_product_dict[product.product_id]
                    res=models.Stock.objects.filter(quantity=stock,stock_id=product.stock).update(quantity=new_stock)
                    if  not res:
                        if i==2:
                            from app01.comment import func
                            transaction.savepoint_rollback(sid)
                            func.add_task(order_id,1)
                            return
                        else:
                            continue
                    else:
                         break
                models.Product.objects.filter(product_id=product.product_id).update(buy_count=new_buy_count)
    
            row=models.Order.objects.filter(order_id=order_id,pay_status=0).update(status="dead")
            if row:
                transaction.savepoint_commit(sid)
            else:
                transaction.savepoint_rollback(sid)
    celery

    wxshopapi2

    """
    Django settings for wxshopapi2 project.
    
    Generated by 'django-admin startproject' using Django 2.0.7.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/2.0/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/2.0/ref/settings/
    """
    
    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = '$v^um*l969ywfw2$3=rv5y&ehv$b@e#w&ha(%t!_+rv3=3#74n'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',
        'rest_framework',
        'xadmin',
        'crispy_forms',
        'reversion',
    ]
    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    
    ROOT_URLCONF = 'wxshopapi2.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'wxshopapi2.wsgi.application'
    
    
    # Database
    # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'wxshop',
            'USER':'root',
            'PASSWORD':'123456',
            'HOST':'127.0.0.1',
            'PORT': 3306,
            'OPTIONS': {'charset': 'utf8mb4'},
        }
    }
    
    
    # Password validation
    # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    
    # Internationalization
    # https://docs.djangoproject.com/en/2.0/topics/i18n/
    
    LANGUAGE_CODE = 'zh-Hans'
    
    TIME_ZONE = 'Asia/Shanghai'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = False
    
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/2.0/howto/static-files/
    
    STATIC_URL = '/static/'
    
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,'static'),
     ]
    MEDIA_ROOT=os.path.join(BASE_DIR,'static/media')
    
    MEDIA_URL = '/static/media/'
    CACHES = {
        'default': {
            'BACKEND': 'django_redis.cache.RedisCache',
            'LOCATION': 'redis://127.0.0.1:6379',
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            },
        },
    }
    settings
    """wxshop URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/2.0/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  path('', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.urls import include, path
        2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
    """
    from django.contrib import admin
    from django.urls import path
    import xadmin
    xadmin.autodiscover()
    
    # version模块自动注册需要版本控制的 Model
    from xadmin.plugins import xversion
    xversion.register_models()
    from django.conf.urls import url
    from  app01.views import User,Banner,Goods,Category,Order
    urlpatterns = [
        path(r'xadmin/', xadmin.site.urls),
        path('admin/', admin.site.urls),
        path("user/wxapp/login",User.Login.as_view()),
        path("banner/list",Banner.List.as_view()),
        path("hotgoods/list",Goods.HotGoods.as_view()),
        path("category/all",Category.All.as_view()),
        path("goods/list",Goods.List.as_view()),
        path("goods/detail",Goods.Detail.as_view()),
        path("order/create",Order.Creat.as_view()),
    ]
    urls
  • 相关阅读:
    2021,6,10 xjzx 模拟考试
    平衡树(二)——Treap
    AtCoder Beginner Contest 204 A-E简要题解
    POJ 2311 Cutting Game 题解
    Codeforces 990G GCD Counting 题解
    NOI2021 SDPTT D2T1 我已经完全理解了 DFS 序线段树 题解
    第三届山东省青少年创意编程与智能设计大赛总结
    Luogu P6042 「ACOI2020」学园祭 题解
    联合省选2021 游记
    Codeforces 1498E Two Houses 题解 —— 如何用结论吊打标算
  • 原文地址:https://www.cnblogs.com/LZXlzmmddtm/p/11823861.html
Copyright © 2011-2022 走看看