递归与树的写法

data:

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},
]
#需求
'''
问题:
我们数据不是有序的,但是我们要排序,并归类,把父集放在子集的前面,辈分等级通过level标明 '''

实现的方法

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

实现树状的等级分类

'''
问题: 因为前端,需要通过循环多少成来,展示多个等级
for item in data:
print(item.name)
for item1 in item.children
item1.name 归档:我要把我的子集,都放在我的children列表里面 '''
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

分析

多种支付的设计

  例如实现微信或支付宝等支付接口的封装.

封装的支付接口方法

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)

pay.Alipay.py

class Alipay():
def pay(self):
pass
"order/notify/Alipay" def notity(self,data):
data['shangcheng_id']
data['sucess']
if data['sucess']="":
return_data['stauts']="success"
return_data['order_id'] = data['shangcheng_id']
return return_data
else:
pass

pay.Wxpay.py

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

支付的接通

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 django.db import transaction from django import forms
import importlib 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.savepoint_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.savepoint_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.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": 200, "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":"缺少参数"})

celery实现订单的回退

  简单的理解就是通过celery异步回调的机制,设置代码段过多少时间之后再去工作,把发起订单后为支付的数据信息返回。

task方法:

from pro_celery.celery import del_order
def add_task(order_id,seconds=5):
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)

celery.py方法的封装

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订单的回退实现的更多相关文章

  1. 菜鸟笔记:node.js+mysql中将JSON数据构建为树(递归制作树状菜单数据接口)

    初学Web端开发,今天是第一次将所学做随笔记录,肯定存在多处欠妥,望大家海涵:若有不足,望大家批评指正. 进实验室后分配到的第一个项目,需要制作一个不确定层级树形菜单的数据接口,对于从来没实战编过程的 ...

  2. ASP.NET通过递归添加树(Treeview)

    先来看看效果,基本上就是这样的. 所谓树,无非就是2点,第一个:根节点,第二:叶子节点,其中叶子节点中还可能有叶子节点,但是根节点始终只有一个. 下面贴上 各部分的代码 1.PAGE_LOAD载入事件 ...

  3. C# 递归构造树状数据结构(泛型),如何构造?如何查询?

    十年河东,十年河西,莫欺少年穷. 学无止境,精益求精 难得有清闲的一上午,索性写篇博客. 首先,我们需要准备一张表,如下范例: create table TreeTable ( TreeId ) no ...

  4. oracle的递归运算(树运算) 无限树形

    oracle的递归运算(树运算)start with org_id ='1'connect by prior parent_id=son_id 1.前言   oracle的递归运算,在我们web页面的 ...

  5. LeetCode--二叉树2--运用递归解决树的问题

    LeetCode--二叉树2--运用递归解决树的问题 在前面的章节中,我们已经介绍了如何利用递归求解树的遍历. 递归是解决树的相关问题最有效和最常用的方法之一. 我们知道,树可以以递归的方式定义为一个 ...

  6. 微信公众号中的支付宝支付与微信支付 && 支付宝支付问题(微信bug)

    一般,在微信公众号中的商城都是需要支持微信支付和支付宝支付的,当然,较大的公司对于鹅厂和阿里的站队就不说了,所以这里简单记录一下支付宝支付和微信支付的主要流程.说是简单介绍,这是因为确实不难,因为前端 ...

  7. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_6-1.常用的第三方支付和聚合支付介绍

    笔记 第六章 开发在线教育视频站点核心业务之从零基础接入 微信扫一扫网页支付 1.常用的第三方支付和聚合支付介绍     简介:介绍常用的第三方支付和聚合支付 1.什么是第三方支付         第 ...

  8. Java之微信支付(扫码支付模式二)案例实战

    摘要:最近的一个项目中涉及到了支付业务,其中用到了微信支付和支付宝支付,在做的过程中也遇到些问题,所以现在总结梳理一下,分享给有需要的人,也为自己以后回顾留个思路. 一:微信支付接入准备工作: 首先, ...

  9. iOS-集成支付宝支付、微信支付简单总结

    支付宝快捷支付: 官方文档中,支付宝说建议我们使用支付时要讲签名过程放在服务器端,这样安全.同时给的demo中签名是在本地移动端做的...不过支付宝的集成还是较简单的. 为了安全签名当然放后台做了.我 ...

随机推荐

  1. MESI缓存一致性协议

    整理一下一些计算机的基础概念. 概念 MESI(Modified, Exclusive, Shared, Invalid) 也称 Illinois 协议, 由美帝UIUC(University of ...

  2. 用Git管理项目进行版本控制

    一.安装 1.1windows 要在Windows系统中安装Git,请访问http://msysgit.github.io/,并单击Download.安装. 1.2 在 Linux 系统中安装 Git ...

  3. oracle将字符串根据特定字符串拆分为多个子字符串

    将 字符串 '20180321-4768-4735261' 按‘-’  拆分: 语法: INSTR()函数 1.用处: 在一个字符串中查找指定的字符,返回被查找到的指定的字符的位置. 2.语法格式: ...

  4. NSPredicate实现数据筛选

    一:基本语法 1.什么是NSPredicate apple官方文档这样写的: The NSPredicate class is used to define logical conditions us ...

  5. 【LeetCode】 240. 搜索二维矩阵 II

    题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有矩阵 mat ...

  6. 基础语法-循环结构for

    基础语法-循环结构for 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.for循环格式 for(初始化表达式;循环条件表达式;循环后的操作表达式){ 执行语句(循环体); } ...

  7. swift中使用UIColllectionView实现横向轮播的一般方法

    // //  HomeLiveRankCell.swift //  YYSwiftProject // //  Created by Domo on 2018/7/28. //  Copyright ...

  8. Codeforces 446C 线段树 递推Fibonacci公式

    聪哥推荐的题目 区间修改和区间查询,但是此题新颖之处就在于他的区间修改不是个定值,而是从L 到 R 分别加 F1.F2....Fr-l+1 (F为斐波那契数列) 想了一下之后,觉得用fib的前缀和来解 ...

  9. Upgrade to 17.1 from 17.0 problem:UnicodeEncodeError: 'ascii' codec can't encode character '\xc4' in position 50: ordinal not in range(128)

    最近 gentoo 从 17.0 更新到 17.1, 需要手动进行升级配置,使用 unsymlink-lib -p --finish 这一步的时候报错,报错如下: /usr/lib/python-ex ...

  10. 实验吧Web-难-头有点大(http头伪造:浏览器、国家、.Net framework版本)

    进去网站显示: 此处告诉我们要干三件事: (1).net framework 版本为9.9 (2)告诉服务器我们的地址为英国 (3)我们访问站点用的是IE 下面我们就抓的包中伪造. 1:.net fr ...