# 类别表 创自关联
class Cate(models.Model):
name = models.CharField(max_length=20, verbose_name="类别名")
# related_name 是用于反向查询时使用的,
# 原来: Cate.cid.all() == Cate.subs.all() 便于简化查询
cid = models.ForeignKey("self",related_name='son', on_delete=models.CASCADE, null=True, blank=True)
class Meta:
db_table = "tb_cate"
def __str__(self):
return self.name
# 品牌
class BrandsModel(models.Model):
name = models.CharField(max_length=16, verbose_name="品牌名")
first_name= models.CharField(max_length=5, verbose_name="首字母")
img = models.CharField(max_length=128, verbose_name="图片地址")
class Meta:
db_table = 'tb_brands'
def __str__(self):
return self.name
class SPU(models.Model):
"商品SPU,如小米手机10;苹果13"
name = models.CharField(max_length=20, verbose_name="spu")
brand = models.ForeignKey(BrandsModel, on_delete=models.PROTECT, verbose_name='品牌')
category1 = models.ForeignKey(Cate, on_delete=models.PROTECT, related_name='cate1_spu', verbose_name='一级类别')
category2 = models.ForeignKey(Cate, on_delete=models.PROTECT, related_name='cate2_spu', verbose_name='二级类别')
category3 = models.ForeignKey(Cate, on_delete=models.PROTECT, related_name='cate3_spu', verbose_name='三级类别')
comment_num = models.IntegerField(verbose_name="评论量",default=0)
sales = models.IntegerField(verbose_name="销量",default=0)
desc_detail = models.TextField(default='', verbose_name='详细介绍')
desc_pack = models.TextField(default='', verbose_name='包装信息')
desc_service = models.TextField(default='', verbose_name='售后服务')
class Meta:
db_table = 'tb_spu'
def __str__(self):
return self.name
class SKU(models.Model):
"""
商品表
名称、描述、价格、库存、商品详情、商品默认图片、分类
"""
name = models.CharField(max_length=100)
describe = models.CharField(max_length=500)
price = models.DecimalField(max_digits=8, decimal_places=2)
stock = models.IntegerField(default=0)
detail = models.TextField(null=True, blank=True)
image_default = models.CharField(verbose_name="默认图片的地址", null=True, blank=True,max_length=300)
is_selling = models.BooleanField(default=True)
sales = models.IntegerField(verbose_name="销量", default=0)
# 一级分类
cate = models.ForeignKey(Cate, on_delete=models.CASCADE)
spu = models.ForeignKey(SPU, on_delete=models.CASCADE, verbose_name='商品SPU')
class Meta:
db_table = 'tb_sku'
def __str__(self):
return self.name
## 自关联实例:
# 模型类
class Cate(models.Model):
name = models.CharField('分类名', max_length=20)
cid = models.ForeignKey('self', related_name='son', on_delete=models.CASCADE, null=True)
## 然后自定序列化器 CateSer
视图代码
# 获取自关联一二三级分类
class Category(APIView):
def get(self, request):
# 获取前端cate_id
cate_id = request.query_params.get('cid_id')
# 如果获取到父级的id,则获取下面的信息
if cate_id:
cls = Cate.objects.filter(pk=cate_id).first()
cate2 = cls.son
# 如果没有参数,通过参数获取所有的顶级父类
else:
cate2 = Cate.objects.filter(cid__isnull=True).all()
# cate2 = Cate.objects.filter(cid=None).all()
ser = CateSer(cate2, many=True)
return Response({'code': 200, 'msg': '获取分类成功', 'cate': ser.data})
路由
path('category/', views.Category.as_view())
## 前端代码
<template>
<div>
<div>
<span v-for="(item, i) in cateList" :key="i">
<el-button @click="Cate2(item.id)">{{ item.name }}</el-button>
</span>
</div>
<div>
<span v-for="(item, i) in cateList2" :key="i">
<el-button @click="Cate3(item.id)">{{ item.name }}</el-button>
</span>
</div>
<div>
<span v-for="(item, i) in cateList3" :key="i">
<router-link :to="{ name: 'Index2', params: { cid_id: item.id } }">
<el-button>{{ item.name }}</el-button>
</router-link>
</span>
</div>
</div>
</template>
data() {
return {
cateList: [], # 一级分类
cateList2: [], # 二级分类
cateList3: [], # 三级分类
};
},
methods: {
Cate() {
axios.get('/books/category/')
.then((resp) => {
console.log(resp)
this.cateList = resp.data.cate
}).catch((err) => {
console.log(err)
});
},
Cate2(id) {
axios.get('/books/category/?cid_id=' + id)
.then((resp) => {
console.log(resp)
this.cateList2 = resp.data.cate
}).catch((err) => {
console.log(err)
});
},
Cate3(id) {
axios.get('/books/category/?cid_id=' + id)
.then((resp) => {
console.log(resp)
this.cateList3 = resp.data.cate
}).catch((err) => {
console.log(err)
});
}
},