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
  • 相关阅读:
    生成器
    迭代器
    装饰器
    Maven工具学习(六)----Maven依赖的版本锁定与版本常量
    SpringBoot学习记录之整合JSP
    SpringBoot学习记录之入门篇
    【k8s】ep-addresses
    【k8s】ep-metadata
    【k8s】Endpoints
    【k8s】cj-suspend
  • 原文地址:https://www.cnblogs.com/LZXlzmmddtm/p/11823861.html
Copyright © 2011-2022 走看看