day88_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

猜你喜欢

转载自www.cnblogs.com/LZXlzmmddtm/p/11823861.html
今日推荐