什么是SPU?什么是SKU
SPU:是标准化产品单元
SKU:库存量单位
创建创建模型类
创建spu跟sku的模型类
关联品牌表跟种类表(继续在后台项目中)
from django.db import models
# spu 表
class SPUS(models.Model):
name=models.CharField('spu',max_length=20)
# #绑定品牌表
brand=models.ForeignKey(Brand,on_delete=models.CASCADE,verbose_name='所属品牌')
# #商品种类表 #反向查询可以直接调用
category1=models.ForeignKey(Cate,on_delete=models.CASCADE,related_name='cate1_spu',verbose_name='一级类别')
category2=models.ForeignKey(Cate,on_delete=models.CASCADE,related_name='cate2_spu',verbose_name='二级类别')
category3=models.ForeignKey(Cate,on_delete=models.CASCADE,related_name='cate3_spu',verbose_name='三级类别')
comment_num=models.IntegerField('评论量',default=0)
sales=models.IntegerField('销量',default=0)
desc_detail=models.TextField('详细描述',default='')
desc_pack=models.TextField('包装信息',default='')
desc_service=models.TextField('售后服务',default='')
def __str__(self):
return self.name
class Meta:
db_table='spu'
# 'sku' 商品表
class SKUS(models.Model):
name=models.CharField('sku',max_length=100)
describe=models.CharField('商品描述',max_length=500)
price=models.DecimalField('价格',decimal_places=2,max_digits=8)
stick=models.IntegerField('库存',default=0)
sales=models.IntegerField('销量',default=0)
detail=models.TextField('详情',default='')
image_default=models.CharField('默认图片',max_length=300,default='')
is_selling=models.BooleanField('是否在售',default=True) #布尔类型
# #绑定商品种类表
cate=models.ForeignKey(Cate,on_delete=models.CASCADE,verbose_name='一级类别')
# #绑定spu表
spu=models.ForeignKey(SPUS,on_delete=models.CASCADE,verbose_name='所属SPU')
def __str__(self):
return self.name
class Meta:
db_table='sku'
verbose_name_plural='商品sku'
生成迁移文件进行迁移
往里边写一条数据
编写序列化器
from rest_framework import serializers
from .models import *
#SKU模型类的序列化器
class SKUSer(serializers.ModelSerializer):
cate_name=serializers.SerializerMethodField(read_only=True)
def get_cate_name(self,obj):
return obj.cate.name
class Meta:
model=SKUS
fields='__all__'
read_only_fields=['id','detail','image_default','sales']
#SPU模型类的序列化器
class SPUSer(serializers.ModelSerializer):
class Meta:
model=SPUS
fields=['id','name']
read_only_fields=['id']
编写视图类
from rest_framework.viewsets import ModelViewSet
from .serializers import *
from .models import *
# sku视图集
class SKUAPIView(ModelViewSet):
queryset = SKUS.objects.all()
serializer_class = SKUSer
lookup_field = 'pk'
lookup_url_kwarg = 'pk'
#spu的视图
class SPUAPIView(ModelViewSet):
queryset = SPUS.objects.all()
serializer_class = SPUSer
配置路由
from django.urls import path
from rest_framework import routers
from .views import *
urlpatterns = [
#频道组的接口,获取所有、新增一个
path('channels/',ListCreateGroupAPIView.as_view()),
#频道组的接口,检索,更改,删除
path('channels/<int:pk>/',ReUpDeAPIViwe.as_view()),
#加载所有的一级类别
path('channels/firstcates/',FirstCateAPIView.as_view())
]
#品牌的路由
router=routers.SimpleRouter()
router.register('brands',BrandViewSet,'brands')
#spu跟sku的路由
router.register('skus',SKUAPIView,'skus')
router.register('spus',SPUAPIView,'spus')
urlpatterns+=router.urls
前端
找到对应的veu组件,进行配置
实现sku的增删改查
例如:Sku.vue 获取全部数据
<script>
import BreadCrumb from "@/components/widget/BreadCrumb";
// 传递到子组件进行功能实现 添加数据
import AddSku from "@/components/widget/AddSku";
// 展示 修改 删除数据
import SkuTable from "@/components/widget/SkuTable";
import cons from "@/components/constant";
export default {
name: "Sku",
data() {
return {
keyword: "",
page: 1,
pagesize: 3,
aSkuList: [],
total: 0,
pop_show: false,
};
},
components: {
BreadCrumb,
AddSku,
SkuTable,
},
mounted() {
this.fnGetData(1);
},
methods: {
// 获取所有的数据
fnGetData(num) {
this.axios
.get("/v1/goods/skus/", {
params: {
page: num,
pageSize: this.pagesize,
},
headers: {
Authorization: "JWT " + localStorage.token,
},
responseType: "json",
})
.then((result) => {
console.log(result);
this.aSkuList = result.data;
})
.catch((err) => {
console.log(err);
});
},
// 切换分页时触发的方法
},
};
</script>
例如:AddSku.vue进行添加数据
修改事件中的路由,字段等
添加绑定外键的字段实现下拉框添加
<script>
let token = localStorage.token;
export default {
name: "AddUser",
data() {
return {
pop_show: false,
skuForm: {
name: "",
spu: "",
describe: "",
cate: "",
price: "",
cost_price: "",
market_price: "",
stick: "",
is_selling: "",
},
category_list: [],
spus_list: [],
};
},
methods: {
// 获取所有的一级类别
fnGetCategory() {
this.axios
.get("/v1/goods/channels/firstcates/", {
headers: {
Authorization: "JWT " + token,
},
responseType: "json",
})
.then((res) => {
this.category_list = res.data;
})
.catch((err) => {
console.log(err.response);
});
},
// 获取所有的spu
fnGetSPUs() {
this.axios
.get("/v1/goods/spus/", {
headers: {
Authorization: "JWT " + token,
},
responseType: "json",
})
.then((res) => {
this.spus_list = res.data;
})
.catch((err) => {
console.log(err.response);
});
},
// 点击提交触发得分方法
submitForm() {
this.axios
.post("/v1/goods/skus/",
this.skuForm,
{
headers: {
Authorization: "JWT " + token,
},
responseType: "json",
}
)
.then((res) => {
if (res.status == 201) {
this.$message({
type: "success",
message: "商品添加成功!",
});
this.pop_show = false;
this.$ref['userForm'].resetFields()
this.$emit("fnResetTable");
}else{
this.$message({
type: "error",
message: "商品添加失败!",
});
}
})
.catch((err) => {
if (err.response.status == 400) {
this.$message({
type: "info",
message: err.response.data.name[0],
});
}
});
},
resetForm() {
this.skuForm.name = "";
this.skuForm.spu = "";
this.skuForm.describe = "";
this.skuForm.cate = "";
this.skuForm.price = "";
this.skuForm.cost_price = "";
this.skuForm.market_price = "";
this.skuForm.stick = "";
this.skuForm.is_selling = "";
},
},
computed: {
look_good_id() {
return this.skuForm.spu_id;
},
},
mounted() {
this.fnGetCategory();
this.fnGetSPUs();
},
watch: {},
};
</script>
例如:SkuTable.vue进行修改数据
修改事件中的路由,字段等
添加绑定外键的字段实现下拉框添加
<script>
import cons from "@/components/constant";
let token = localStorage.token;
export default {
name: "SkuTable",
// 接收父组件传来的值
props: ["skus"],
data() {
return {
pop_show: false,
edit_id: 0,
skuForm: {
name: "",
spu: "",
describe: "",
cate: "", //类别id
price: "",
cost_price: "",
market_price: "",
stick: "",
is_selling: "",
cate_name: "", // 分类的名字
},
// 所有分类
category_list: [],
spus_list: [],
specs_list: [],
};
},
methods: {
// 获取分类信息 获取一级类别
fnGetCategory() {
this.axios
.get("/v1/goods/channels/firstcates/", {
headers: {
Authorization: "JWT " + token,
},
responseType: "json",
})
.then((res) => {
this.category_list = res.data;
})
.catch((err) => {
console.log(err.response);
});
},
// 获得spu数据
fnGetSPUs() {
this.axios
.get("/v1/goods/spus/", {
headers: {
Authorization: "JWT " + token,
},
responseType: "json",
})
.then((res) => {
console.log("加载spus>>>", res.data);
this.spus_list = res.data;
})
.catch((err) => {
console.log(err.response);
});
},
// 点击修改按钮触发的方法
fnPopShow(id) {
// 显示弹窗
this.pop_show = true;
this.edit_id = id;
this.axios
.get("/v1/goods/skus/" + id + "/", {
headers: {
Authorization: "JWT " + token,
},
responseType: "json",
})
.then((res) => {
this.skuForm.name = res.data.name;
this.skuForm.describe = res.data.describe;
this.skuForm.price = res.data.price;
this.skuForm.market_price = res.data.price;
this.skuForm.cost_price = res.data.price;
this.skuForm.stick = res.data.stick;
this.skuForm.is_selling = res.data.is_selling;
this.skuForm.cate = res.data.cate; // 分类的id
this.skuForm.cate_name = res.data.cate_name; // 分类的名字
// this.skuForm.spu_name = dat.data.spu_name; // spu的名字
this.skuForm.spu = res.data.spu; // spu的id
})
.catch((err) => {
console.log(err.response);
});
},
// 修改数据提交
submitForm() {
this.axios
.put("/v1/goods/skus/" + this.edit_id + "/",
this.skuForm,
{
headers: {
Authorization: "JWT " + token,
},
responseType: "json",
}
)
.then((res) => {
console.log('更新sku的响应',res);
this.$message({
type: "success",
message: "商品修改成功!",
});
this.pop_show = false;
this.$emit("fnResetTable");
})
.catch((err) => {
if (err.response.status == 400) {
this.$message({
type: "info",
message: err.response.data.name[0],
});
}
});
},
// 删除功能
fnDelSku(id) {
this.edit_id = id;
this.$confirm("此操作将删除该商品, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.axios
.delete("/v1/goods/skus/" + this.edit_id + "/", {
headers: {
Authorization: "JWT " + token,
},
responseType: "json",
})
.then((dat) => {
this.$message({
type: "success",
message: "删除成功!",
});
this.$emit("fnResetTable");
})
.catch((err) => {
if (err.response.status == 404) {
this.$message({
type: "info",
message: "商品未找到!",
});
}
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
},
computed: {
look_good_id() {
return this.skuForm.spu_id;
},
},
watch: {}
},
mounted() {
//加载一级类别
this.fnGetCategory();
//加载spu
this.fnGetSPUs();
},
};
</script>