更新SKU表数据
1、 获取修改商品的详情信息
点就修改按钮时,我们需要先获取要修改的商品详情信息
接口分析
请求方式: GET /meiduo_admin/skus/(?P\d+)/
请求参数: 通过请求头传递jwt token数据。
在头部中携带要获取的spu商品ID
返回数据: 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"
},
...
]
}
参数类型是否必须说明namestr是商品SKU名称spu_idint是商品SPU IDcaptionstr是商品副标题category_idint是三级分类IDpriceint是价格cost_priceint是进价market_priceint是市场价stockint是库存is_launchedboole是上下架
后端实现
# SKUGoodsView继承的是ModelViewSet 所以获取单一spu商品逻辑还是使用同一个类视图
class SKUGoodsView(ModelViewSet):
serializer_class =SKUGoodsSerializer
pagination_class = PageNum
def 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)
接口分析
请求方式: PUT meiduo_admin/skus/(?P\d+)/
请求参数: 通过请求头传递jwt token数据。
参数类型是否必须说明namestr是商品SKU名称spu_idint是商品SPU IDcaptionstr是商品副标题category_idint是三级分类IDpriceint是价格cost_priceint是进价market_priceint是市场价stockint是库存is_launchedboole是上下架返回数据: 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"
},
...
]
}
参数类型是否必须说明namestr是商品SKU名称spu_idint是商品SPU IDcaptionstr是商品副标题category_idint是三级分类IDpriceint是价格cost_priceint是进价market_priceint是市场价stockint是库存is_launchedboole是上下架
后端实现
# SKUGoodsView继承的是ModelViewSet 所以更新逻辑还是使用同一个类视图
class SKUGoodsView(ModelViewSet):
serializer_class =SKUGoodsSerializer
pagination_class = PageNum
def get_queryset(self):
keyword=self.request.query_params.get('keyword')
if keyword == '':
return SKU.objects.all()
else:
return SKU.objects.filter(name=keyword)
序列化器定义:
class SKUSerializer(serializers.ModelSerializer):
"""
SKU表数据
"""
# 返回关联spu表的名称和关联的分类表的名称
spu = serializers.StringRelatedField(read_only=True)
category = serializers.StringRelatedField(read_only=True)
# 返回模型类类的spu_id和category_id
spu_id = serializers.IntegerField()
category_id = serializers.IntegerField()
# 返回商品的规格信息 ,在商品规格详情表(SKUSpecification)中有个外键sku关了当前的SKU表
specs = SKUSpecificationSerializer(many=True)
class Meta:
model = SKU
fields = "__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
def update(self, instance, validated_data):
# 获取规格信息
specs = self.context['request'].data.get('specs')
# 因为sku表中没有specs字段,所以在保存的时候需要删除validated_data中specs数据
del validated_data['specs']
with transaction.atomic():
# 开启事务
sid = transaction.savepoint()
try:
# 1、更新sku表
SKU.objects.filter(id=instance.id).update(**validated_data)
# 2、更新SKU具体规格表
for spec in specs:
SKUSpecification.objects.create(sku=instance, 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(instance.id)
return instance