商品详情的无限极分类
--北京 --朝阳区 ---上海 --松江 --大学城
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 # 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(data,parent_id=item[‘cat_id‘],is_clear=False) return res_id 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
商品分类列表
前端部分
后端
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": "没有该商品"})
前端
<import src="../../wxParse/wxParse.wxml" /> <navigation id=‘Navigation‘ show-icon="{{true}}" title="商品详情" show-title="{{true}}" class=""></navigation> <view class="container"> <view class="swiper-container"> <image src="{{goodsDetail.image_url}}" class="slide-image" lazy-load="true" /> </view> <view class="goods-info"> <view class="goods-left"> <view class="goods-title">{{goodsDetail.name}}</view> <view class="goods-characteristic">{{goodsDetail.intor}}</view> <view class="goods-price">? {{goodsDetail.price}}</view> <view class="piangjia"> 已售 {{goodsDetail.buy_count}} </view> </view> </view> <view class="tab-header" bindtap="tabFun"> <view class="{{tabArr.curHdIndex==‘0‘? ‘active‘ : ‘‘}}" id="tab-hd01" data-id="0">商品介绍</view> <view class="{{tabArr.curHdIndex==‘1‘? ‘active‘ : ‘‘}}" id="tab-hd02" data-id="1">商品评价</view> </view> <view class="tab-container"> <view class="tab-item {{tabArr.curBdIndex==‘0‘? ‘active‘ : ‘‘}}"> <view class="goods-text"> <template is="wxParse" data="{{wxParseData:article.nodes}}" /> </view> </view> <view class="tab-item {{tabArr.curBdIndex==‘1‘? ‘active‘ : ‘‘}}"> <view class="reputation-none" wx:if="{{!reputation}}"> <image src="../../images/empty_comment.png" /> 还没有人评价 </view> <view class="goods-reputa-list" wx:for="{{reputation}}" wx:key="id"> <view class="goods-reputa-avatar"> <image class="goods-avatar" src="{{item.user.avatarUrl}}"></image> </view> <view class="goods-reputa-mark"> <view class="goods-reputa-user"> {{item.user.nick}} <text>{{item.goods.goodReputationStr}}</text> </view> <view class="goods-mark">{{item.goods.goodReputationRemark}}</view> <view class="goods-mark-day"> {{item.goods.dateReputation}} <text>{{item.goods.property}}</text> </view> </view> </view> </view> </view> <view class="footer-box"> <view class="box-list"> <image src="../../images/goods_service.png"></image> <button open-type="contact" session-from="weapp"></button> </view> <view class="box-list" bindtap="goShopCar"> <image src="../../images/shopping_cart.png"></image> <view class="shop-num">{{shopNum}}</view> </view> <view class="box-list" > </view> <view class="box-title"> <view class="box-shop-cart npx" bindtap="tobuy">立即购买</view> </view> <view class="box-title buy-now"> <view class="box-now-buy npx" bindtap="toAddShopCar">加入购物车1</view> </view> </view> <view class="show-popup" hidden="{{hideShopPopup}}"> <view class="popup-mask" bindtap="closePopupTap"></view> <view class="popup-contents"> <view class="pop-goods-info"> <view class="pop-img-box"> <image src="{{goodsDetail.image_url}}" class="goods-thumbnail" /> </view> <view class="pop-goods-des"> <view class="pop-goods-title">{{goodsDetail.name}}</view> <view class="pop-goods-price" >¥ {{goodsDetail.price}}</view> </view> <view class="pop-goods-close" bindtap="closePopupTap"></view> </view> <view class="buy-num-box"> <view class="num-label">购买数量</view> <view class="num-box"> <view class="num-jian {{buyNumber == buyNumMin ? ‘hui‘: ‘‘}}" bindtap="numJianTap">-</view> <view class="num-input"> <input type="number" value="{{buyNumber}}" disabled/> </view> <view class="num-jia {{buyNumber== buyNumMax ? ‘hui‘: ‘‘}}" bindtap="numJiaTap"> </view> </view> </view> <view class="popup-join-btn" wx:if="{{shopType ==‘addShopCar‘}}" bindtap="addShopCar">加入购物车</view> <view class="popup-join-btn" wx:if="{{shopType ==‘tobuy‘}}" bindtap="buyNow"> 立即购买</view> </view> </view> </view>View Code
事务的隔离级别
事务的四大特性分别是:原子性、一致性、隔离性、持久性
解释
""" 原子性: 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
一致性: 执行事务前后,数据保持一致;
隔离性: 并发访问数据库时,一个用户的事物不被其他事物所干扰,各并发事务之间数据库是独立的;
持久性: 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。 """
并发事务带来的问题
在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对统一数据进行操作)。
并发虽然是必须的,但可能会导致一下的问题。
脏读(Dirty read):
事务T1正在操作一条数据,此时事务T2获取该条数据纪录,如果T1异常,事务回滚,T2读取到的数据就是脏数据,这种现象称为脏读。
不可重复读(Unrepeatableread):
事务T1多次读取某条记录,在读取间隔中,事务T2更新了该技术的数据,当T1再次读取该记录时,获取到的数据不一致,这种现象称为不可重复读。产生的原因主要是数据的更新。
幻读(Phantom read):
幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,
第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。
可重复读(Repeatable read):
①定义:就是一个事务对同一份数据读取到的相同,不在乎其他事务对数据的修改。MySQL默认的隔离级别。
②缺点:会产生幻读。
序列化(Serializable)
①定义:事务串行化执行,隔离级别最高,牺牲了系统的并发性。
②缺点:可以解决并发事务的所有问题。但是效率地下,消耗数据库性能,一般不使用。
乐观锁和悲观锁
概念
#悲观锁:总是假设最坏的情况,认为竞争总是存在,每次拿数据的时候都认为会被修改,因此每次都会先上锁。其他线程阻塞等待释放锁。 #乐观锁:总是假设最好的情况,认为竞争总是不存在,每次拿数据的时候都认为不会被修改,因此不会先上锁,在最后更新的时候比较数据有无更新,可通过版本号或CAS实现。
两种锁的使用场景
悲观锁:用于写比较多的情况,避免了乐观锁不断重试从而降低性能。
乐观锁:用于读比较多的情况,避免了不必要的加锁的开销。