SKU表管理之保存SKU表数据
保存SKU表数据
在保存数据之前我们需要先获取三级分类信息、SPU表的名称信息、当前SPU商品的规格选项信息加载到页面中
1、获取三级分类信息
接口分析
请求方式: GET /meiduo_admin/skus/categories/
# -------获取三级分类信息--------url(r'skus/categories/$', skus.SKUCategorieView.as_view()),
【图片中重写的方法名,作用相同于下面写的类方法】
请求参数: 通过请求头传递jwt token数据。
返回数据: JSON
[{"id": "商品分类id","name": "商品分类名称"},...]
返回值 | 类型 | 是否必须 | 说明 |
---|---|---|---|
Id | int | 是 | 商品分类id |
name | 数组 | 是 | 商品分类名称 |
后端实现
from rest_framework.viewsets import ModelViewSet
from meiduo_admin.serializers.skus import SKUGoodsSerializer
from meiduo_admin.utils import UserPageNum
from goods.models import SKU
from rest_framework.generics import ListAPIView
from meiduo_admin.serializers.skus import SKUCategorieSerializer
from goods.models import GoodsCategoryclass SKUCategorieView(ListAPIView):serializer_class = SKUCategorieSerializer# 根据数据存储规律parent_id大于37为三级分类信息,查询条件为parent_id__gt=37queryset = GoodsCategory.objects.filter(parent_id__gt=37)
序列化器的定义
from rest_framework import serializers
from goods.models import SKU,GoodsCategory
from goods.models import SKUSpecification
from goods.models import GoodsCategoryclass SKUCategorieSerializer(serializers.ModelSerializer):"""商品分类序列化器"""class Meta:model = GoodsCategoryfields = "__all__"
2、获取spu表名称数据
接口分析
请求方式: GET /meiduo_admin/goods/simple/
# -------获取spu表名称数据--------url(r'goods/simple/$', skus.SPUSimpleView.as_view()), # 此行代码和上面规格路由表的作用是一样的
请求参数: 通过请求头传递jwt token数据。
返回数据: JSON
[{"id": "商品SPU ID","name": "SPU名称"},...]
返回值 | 类型 | 是否必须 | 说明 |
---|---|---|---|
Id | int | 是 | 商品SPU ID |
name | 数组 | 是 | SPU名称 |
后端实现
class SPUSimpleView(ListAPIView):serializer_class = SPUSimpleSerializerqueryset = SPU.objects.all()
定义序列化器
class SPUSimpleSerializer(serializers.ModelSerializer):"""商品SPU表序列化器"""class Meta:model = GoodsCategoryfields = ('id', 'name')
3、获取SPU商品规格信息
接口分析
请求方式: GET meiduo_admin/goods/(?P<pk>\d+)/specs/
# -------获取spu商品规格信息--------url(r'goods/(?P<pk>\d+)/specs/$', skus.SPUSpecView.as_view()),
请求参数: 通过请求头传递jwt token数据。
在路径中传递当前SPU商品id
返回数据: JSON
[{"id": "规格id","name": "规格名称","spu": "SPU商品名称","spu_id": "SPU商品id","options": [{"id": "选项id","name": "选项名称"},...]},...]
返回值 | 类型 | 是否必须 | 说明 |
---|---|---|---|
Id | int | 是 | 规格id |
name | Str | 是 | 规格名称 |
Sup | str | 是 | Spu商品名称 |
Spu_id | Int | 是 | spu商品id |
options | 是 | 关联的规格选项 |
后端实现
class SPUSpecView(ListAPIView):serializer_class = SPUSpecSerialzier# 因为我们继承的是ListAPIView,在拓展类中是通过get_queryset获取数据,但是我们现在要获取的是规格信息,所以重写get_querysetdef get_queryset(self):# 获取spuid值pk=self.kwargs['pk']# 根据spu的id值关联过滤查询出规格信息return SPUSpecification.objects.filter(spu_id=self.kwargs['pk'])
定义序列化器
from goods.models import GoodsCategory, SpecificationOption, SPUSpecificationclass SPUOptineSerializer(serializers.ModelSerializer):"""规格选项序列化器"""class Meta:model = SpecificationOptionfields = ('id', 'value')class SPUSpecSerialzier(serializers.ModelSerializer):"""规格序列化器"""# 关联序列化返回SPU表数据spu = serializers.StringRelatedField(read_only=True)spu_id = serializers.IntegerField(read_only=True)# 关联序列化返回 规格选项信息options = SPUOptineSerializer(read_only=True, many=True) # 使用规格选项序列化器class Meta:model = SPUSpecification # SPUSpecification中的外键spu关联了SPU商品表fields = "__all__"
4、保存SKU数据
【保存数据时若不显示,则刷新一下】
接口分析
请求方式: POST meiduo_admin/skus/
# sku表查询路由****************************
router = DefaultRouter()
router.register('skus', skus.SKUGoodsView, base_name='sku')
urlpatterns += router.urls
请求参数: 通过请求头传递jwt token数据。
参数 | 类型 | 是否必须 | 说明 |
---|---|---|---|
name | str | 是 | 商品SKU名称 |
spu_id | int | 是 | 商品SPU ID |
caption | str | 是 | 商品副标题 |
category_id | int | 是 | 三级分类ID |
price | int | 是 | 价格 |
cost_price | int | 是 | 进价 |
market_price | int | 是 | 市场价 |
stock | int | 是 | 库存 |
is_launched | boole | 是 | 上下架 |
返回数据: JSON
{"id": "商品SKU ID","name": "商品SKU名称","goods": "商品SPU名称","goods_id": "商品SPU ID","caption": "商品副标题","category_id": "三级分类id","category": "三级分类名称","price": "价格","cost_price": "进价","market_price": "市场价","stock": "库存","sales": "销量","is_launched": "上下架","specs": [{"spec_id": "规格id","option_id": "选项id"},...]}
参数 | 类型 | 是否必须 | 说明 |
---|---|---|---|
name | str | 是 | 商品SKU名称 |
spu_id | int | 商品SPU ID | |
caption | str | 商品副标题 | |
category_id | int | 三级分类ID | |
price | int | 价格 | |
cost_price | int | 进价 | |
market_price | int | 市场价 | |
stock | int | 库存 | |
is_launched | boole | 上下架 |
后端实现:
在后端实现中,我们需要异步生成详情页静态页面,同时涉及到多张表操作,我们还需要使用事务
# SKUGoodsView继承的是ModelViewSet 所以保存逻辑还是使用同一个类视图
class SKUGoodsView(ModelViewSet):serializer_class =SKUGoodsSerializerpagination_class = PageNumdef get_queryset(self):keyword=self.request.query_params.get('keyword')if keyword == '' or keyword is None:return SKU.objects.all()else:return SKU.objects.filter(name=keyword)
序列化器的定义
from django.db import transaction
from celery_tasks.static_file.tasks import get_detail_htmlclass SKUSerializer(serializers.ModelSerializer):"""SKU表数据"""# 返回关联spu表的名称和关联的分类表的名称spu = serializers.StringRelatedField(read_only=True)category = serializers.StringRelatedField(read_only=True)# 返回模型类类的spu_id和category_idspu_id = serializers.IntegerField()category_id = serializers.IntegerField()# 返回商品的规格信息 ,在商品规格详情表(SKUSpecification)中有个外键sku关了当前的SKU表specs = SKUSpecificationSerializer(many=True)class Meta:model = SKUfields = "__all__"def create(self, validated_data):# self指的是当前序列化器对象,在self下面有个context属性保存了请求对象specs=self.context['request'].data.get('specs')# specs = validated_data['specs']# 因为sku表中没有specs字段,所以在保存的时候需要删除validated_data中specs数据del validated_data['specs']with transaction.atomic():# 开启事务sid = transaction.savepoint()try:# 1、保存sku表sku = SKU.objects.create(**validated_data)# 2、保存SKU具体规格for spec in specs:SKUSpecification.objects.create(sku=sku, spec_id=spec['spec_id'], option_id=spec['option_id'])except:# 捕获异常,说明数据库操作失败,进行回滚transaction.savepoint_rollback(sid)return serializers.ValidationError('数据库错误')else:# 没有捕获异常,数据库操作成功,进行提交transaction.savepoint_commit(sid)# 执行异步任务生成新的静态页面get_detail_html.delay(sku.id)return sku
异步任务:
import osfrom django.conf import settings
from django.shortcuts import renderfrom goods.models import SKU
from meiduo_mall.utils.breadcrumb import get_breadcrumb
from meiduo_mall.utils.categories import get_categories
from celery_tasks.main import app@app.task(name='get_detail_html')
def get_detail_html(sku_id):# 获取当前sku对象sku=SKU.objects.get(id=sku_id)# 分类数据categories = get_categories()# 获取面包屑导航breadcrumb = get_breadcrumb(sku.category)# 获取spuspu = sku.spu# 获取规格信息:sku===>spu==>specsspecs = spu.specs.order_by('id')# 查询所有的sku,如华为P10的所有库存商品skus = spu.skus.order_by('id')'''{选项:sku_id}说明:键的元组中,规格的索引是固定的示例数据如下:{(1,3):1,(2,3):2,(1,4):3,(2,4):4}'''sku_options = {}sku_option = []for sku1 in skus:infos = sku1.specs.order_by('spec_id')option_key = []for info in infos:option_key.append(info.option_id)# 获取当前商品的规格信息if sku.id == sku1.id:sku_option.append(info.option_id)sku_options[tuple(option_key)] = sku1.id# 遍历当前spu所有的规格specs_list = []for index, spec in enumerate(specs):option_list = []for option in spec.options.all():# 如果当前商品为蓝、64,则列表为[2,3]sku_option_temp = sku_option[:]# 替换对应索引的元素:规格的索引是固定的[1,3]sku_option_temp[index] = option.id# 为选项添加sku_id属性,用于在html中输出链接option.sku_id = sku_options.get(tuple(sku_option_temp), 0)# 添加选项对象option_list.append(option)# 为规格对象添加选项列表spec.option_list = option_list# 重新构造规格数据specs_list.append(spec)context = {'sku': sku,'categories': categories,'breadcrumb': breadcrumb,'category_id': sku.category_id,'spu': spu,'specs': specs_list}response = render(None, 'detail.html', context)file_name = os.path.join(settings.BASE_DIR, 'static/detail/%d.html' % sku.id)# 写文件with open(file_name, 'w') as f1:f1.write(response.content.decode())
SKU表管理之保存SKU表数据相关推荐
- 分组表管理之保存分组表数据
保存分组表数据 在保存数据之前我们需要权限表的数据内容展示在权限中 1.获取权限表数据 接口分析 请求方式: GET /meiduo_admin/permission/simple/ # 保存分组表数 ...
- 权限表管理之保存权限表数据
保存权限表数据 在保存数据之前我们需要权限类表数据内容 1.获取权限类型列表数据 接口分析 请求方式: GET /meiduo_admin/permission/content_types/ # 获取 ...
- SPU表管理之保存SPU表数据
保存SPU表数据 在保存数据之前我们需要先获取品牌名称和分类信息 1.获取品牌信息 接口分析 请求方式: GET /meiduo_admin/goods/brands/simple # 获取品牌信息u ...
- 规格表管理之保存规格表数据表数据
保存规格表数据表数据 添加路由: # -------规格路由表--------url(r'goods/simple/$',specs.SpecsView.as_view({'get':'simple' ...
- SKU表管理之更新SKU表数据
更新SKU表数据 1. 获取修改商品的详情信息 点就修改按钮时,我们需要先获取要修改的商品详情信息 接口分析 请求方式: GET /meiduo_admin/skus/(?P<pk>\d+ ...
- SKU表管理之删除SKU表数据
删除SKU表数据 接口分析 请求方式: Delte meiduo_admin/skus/(?P<pk>\d+)/ 请求参数: 通过请求头传递jwt token数据. 在路径中携带删除的sp ...
- 规格选项表管理之保存规格选项表数据
保存规格选项表数据 在保存数据之前我们需要先获取商品规格名称,在规格的下来菜单中展示规格数据 1.获取品牌信息 接口分析 请求方式: GET /meiduo_admin/goods/specs/sim ...
- SPU表管理之更新SPU表数据
更新SPU表数据 1. 获取修改商品的详情信息 点就修改按钮时,我们需要先获取要修改的商品详情信息 接口分析 请求方式: GET /meiduo_admin/goods/(?P<pk>\d ...
- 分组表管理之获取用户组表列表数据
分组表管理 在系统管理中我们需要完成用户组表的增删改查,这时候我们可以借助于视图集中的ModelViewset来完成相应的操作 获取用户组表列表数据 接口分析 请求方式: GET /meiduo_ad ...
最新文章
- 刻意练习:LeetCode实战 -- Task27.分发饼干
- 面试官三连问:分库分表了解吧?业界有哪些常用方案?可能存在什么问题?
- .net中实现拖拽控件
- 网页中插入javascript的几种方法
- 前端学习(3012):vue+element今日头条管理--axios的create字段
- java学习(41):成员实例的定义和访问续
- Poor Man's BERT: 更小更快的Transformer模型
- 64位处理器_快看看你的电脑是64位还是32位操作系统,处理器支持64位可升级
- NMI watchdog: BUG: soft lockup - CPU#2 stuck for 23s!
- matlab求导图形,用MATLAB图形使高等数学问题直观化
- AD画板,如何提高工作效率?
- 使用大白菜装机维护版软件取消Win7开机密码
- dbc批量插入、批量删除、批量更新
- wps手机版ppt动画效果_你不知道的WPS|仅这2个制作PPT的动画技能,就足够让你的PPT逼格瞬间提升...
- 秒杀99.99%大学生!看看清华的学霸到底有多牛?
- 应用统计学与R语言实现学习笔记(三)——描述性统计
- windows网络服务之配置网络负载均衡(NLB)群集
- 超详细的Git学习记录(Git基础内容/IDEA集成Git/GitHub/Gitee/GitLab及Centos7部署GitLab)
- 海康大华等网络摄像机监控视频RTSP/RTMP推流网页播放/直播无需插件低延迟解决方案研究
- Cause: java.lang.IllegalArgumentException
热门文章
- 超棒整理 | Python 关键字知识点大放送
- 不是“重复”造轮子,百度飞桨框架2.0如何俘获人心
- 200万注册开发者,13亿全景图片,90%数据生产AI化,百度地图如何造生态?
- CSDN公众号新功能上线,居然还能搜出小姐姐???
- Python 编程语言的核心是什么?
- 反季大清仓,最低仅需34.9元
- AI应用落地哪家强?CSDN AI Top 30+案例评选等你来秀!
- 68款大规模机器学习数据集,涵盖CV、语音、NLP | 十年资源集
- iPad mini时隔四年更新,搭载A12芯片,起售价2999
- 掌握哪些机器学习工具更受企业青睐?