一。事务的隔离级别。

  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": "",
"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="")
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':'',
'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

最新文章

  1. android studio 导入有so 文件的项目是,程序崩溃的可能原因
  2. php网站验证码的生成
  3. UVa 489 刽子手游戏
  4. android获取手机信息2
  5. 记一次js中和php中的字符串长度计算截取的终极问题和完美解决方案
  6. Unity问答——请教一下NGUI的图片转换问题
  7. codevs 1031 质数环
  8. java求最大公约数(分解质因数)
  9. iis .apk .ipa下载设置
  10. FL Studio中音频ASIO4ALL的设置
  11. 报错:Flink Could not resolve substitution to a value: ${akka.stream.materializer}
  12. 2019.3.28 S21 day02pyth笔记总结
  13. 【Codeforces 848C】Goodbye Souvenir
  14. AGC027 C - ABland Yard 拓扑排序
  15. RabbitMQ--学习资源汇
  16. Ubuntu下彻底卸载wine
  17. Cocos2d-X开发中国象棋《二》project文件概述
  18. Flume的介绍和简单操作
  19. 【BZOJ1441】Min 拓展裴蜀定理
  20. Java进阶7并发优化4——JDK并发数据结构

热门文章

  1. PlayJava Day024
  2. ES 6新语法
  3. leaflet-webpack 入门开发系列四图层控件样式优化篇(附源码下载)
  4. 将Android封装库通过gradle部署到maven私服并依赖使用
  5. 入职小白随笔之Android四大组件——服务(Service)
  6. 5、netty第四个例子,空闲检测handle
  7. 小程序模板template使用介绍
  8. Git入门基础教程
  9. 剑指Offer-42.和为S的两个数字(C++/Java)
  10. ThinkPHP调用其他控制器的方法,助手函数action()