后端
模型层
from django.db import models
# Create your models here.
# 商品种类
class Categor(models.Model):
cat_name = models.CharField('类别名字', max_length=20)
class Meta:
db_table = 'categor'
def __str__(self):
return self.cat_name
# 商品
class Goods(models.Model):
sku_name = models.CharField('商品名字', max_length=100)
price = models.DecimalField(verbose_name='商品价格', max_digits=10, decimal_places=2)
selling_price = models.DecimalField(verbose_name='商品销售', max_digits=10, decimal_places=2)
img = models.CharField('商品默认图片', max_length=200)
title = models.CharField('商品标题', max_length=20, null=True)
instruction = models.TextField(verbose_name='商品描述')
count = models.IntegerField('商品销售数量', default=0)
stock = models.IntegerField('商品存库数量', default=0)
cate = models.ForeignKey(to=Categor, on_delete=models.CASCADE, verbose_name='商品类型')
online = models.BooleanField('是否在售', default=True)
class Meta:
db_table = 'goods'
def __str__(self):
return self.sku_name
# 图片
class GoodImg(models.Model):
img = models.CharField('图片', max_length=100)
title = models.CharField('图片描述', max_length=20, null=True)
good = models.ForeignKey(to=Goods, on_delete=models.CASCADE, verbose_name='商品默认图片')
class Meta:
db_table = 'goodimg'
def __str__(self):
return self.title
视图层
from django.shortcuts import render
from rest_framework.views import APIView
from goods.models import Categor, Goods
from rest_framework.response import Response
from goods.serializers import GoodsSer
# Create your views here.
# 摸一个分类的视图
class IndexView(APIView):
def get(self, request):
cate_name = request.query_params.get('cate_name')
# 获取数据
goods_all = Categor.objects.filter(cat_name=cate_name).first()
# 判断是否存在
if not goods_all:
return Response({
'code': 400,
'msg': '信息不存在'
})
# 获取商品数据
goods_data = goods_all.goods_set.all()[:7]
# 序列化
ser = GoodsSer(goods_data, many=True)
return Response({
'code': 200,
'msg': '获取成功',
'goods': ser.data
})
# 热门商品
class GoodsView(APIView):
def post(self, request):
cate_name = request.data.get('cate_name')
# 获取数据
goods_all = Goods.objects.filter(cate__cat_name__in=cate_name).order_by('-count').all()[:7]
# 序列化
ser = GoodsSer(goods_all, many=True)
return Response({
'code': 200,
'msg': '获取成功',
'goods': ser.data
})
前端vuex
<!--
* @Description: 首页组件
* @Author: hai-27
* @Date: 2020-02-07 16:23:00
* @LastEditors: hai-27
* @LastEditTime: 2020-02-27 13:36:12
-->
<template>
<div class="home" id="home" name="home">
<!-- 轮播图 -->
<div class="block">
<el-carousel height="460px">
<el-carousel-item v-for="item in carousel" :key="item.id">
<img style="height:460px;" :src="item.img" :alt="item.title"/>
</el-carousel-item>
</el-carousel>
</div>
<!-- 轮播图END -->
<div class="main-box">
<div class="main">
<!-- 手机商品展示区域 -->
<div class="phone">
<div class="box-hd">
<div class="title">手机</div>
</div>
<div class="box-bd">
<div class="promo-list">
<!-- 路由跳转,相当于超链接a 手机>图片-->
<router-link to>
<img src="/image/phone.png"/>
</router-link>
</div>
<!-- 手机类 的商品列表 -->
<div class="list">
<!-- 整个块 是MyList组件 -->
<MyList :list="phoneList" :isMore="true" :isDelete="false"></MyList>
</div>
</div>
</div>
<!-- 手机商品展示区域END -->
<!-- 家电商品展示区域 -->
<div class="appliance">
<div class="box-hd">
<div class="title">家电</div>
<div class="more">
<!-- 右上角的菜单组件 -->
<MyMenu :val="2" @fromChild="getChildMsg">
<span slot="1">热门</span>
<span slot="2">电视影音</span>
</MyMenu>
</div>
</div>
<div class="box-bd">
<div class="promo-list">
<ul>
<!-- 家电类别的两张图 -->
<li>
<img src="/image/appliance-promo1.png"/>
</li>
<li>
<img src="/image/appliance-promo2.png"/>
</li>
</ul>
</div>
<!-- 右侧商品列表 -->
<div class="list">
<MyList :list="applianceList" :isMore="true"></MyList>
</div>
</div>
</div>
<!-- 家电商品展示区域END -->
<!-- 配件商品展示区域 -->
<div class="accessory" id="promo-menu">
<div class="box-hd">
<div class="title">配件</div>
<div class="more" id="more">
<MyMenu :val="3" @fromChild="getChildMsg2">
<span slot="1">热门</span>
<span slot="2">保护套</span>
<span slot="3">充电器</span>
</MyMenu>
</div>
</div>
<div class="box-bd">
<div class="promo-list">
<ul>
<li>
<img src="image/accessory-promo1.png" alt/>
</li>
<li>
<img src="image/accessory-promo2.png" alt/>
</li>
</ul>
</div>
<div class="list">
<MyList :list="accessoryList" :isMore="true"></MyList>
</div>
</div>
</div>
<!-- 配件商品展示区域END -->
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
carousel: "", // 轮播图数据 [{},{},....]
phoneList: "", // 手机商品列表 [{},{},....]
miTvList: "", // 小米电视商品列表
applianceList: "", // 展示的家电商品列表
applianceHotList: "", //热门家电商品列表
accessoryList: "", //配件商品列表
accessoryHotList: "", //热门配件商品列表
protectingShellList: "", // 保护套商品列表
chargerList: "", //充电器商品列表
applianceActive: 1, // 家电当前选中的商品分类
accessoryActive: 1 // 配件当前选中的商品分类
};
},
watch: {
// 家电当前选中的'热门'和'电视影音',响应不同的商品数据
applianceActive: function (val) {
// 页面初始化的时候把applianceHotList(热门家电商品列表)直接赋值给applianceList(家电商品列表)
// 在切换商品列表时判断applianceHotList是否为空,为空则是第一次切换,把applianceList赋值给applianceHotList
if (this.applianceHotList == "") {
this.applianceHotList = this.applianceList;
}
if (val == 1) {
// 1为热门商品
this.applianceList = this.applianceHotList;
return;
}
if (val == 2) {
// 2为电视商品
this.applianceList = this.miTvList;
return;
}
},
accessoryActive: function (val) {
// 页面初始化的时候把accessoryHotList(热门配件商品列表)直接赋值给accessoryList(配件商品列表)
// 所以在切换商品列表时判断accessoryHotList是否为空,为空则是第一次切换,把accessoryList赋值给accessoryHotList
if (this.accessoryHotList == "") {
this.accessoryHotList = this.accessoryList;
}
if (val == 1) {
// 1为热门商品
this.accessoryList = this.accessoryHotList;
return;
}
if (val == 2) {
// 2为保护套商品
this.accessoryList = this.protectingShellList;
return;
}
if (val == 3) {
//3 为充电器商品
this.accessoryList = this.chargerList;
return;
}
}
},
// 组件创建完成时,加载数据
created() {
// TODO 获取轮播图数据
this.$axios.get('/user/img2/')
.then(res =>{
if (res.data.code == 200) {
this.carousel = res.data.img
} else {
this.notifyError(res.data.msg)
}
}).catch(err =>{
console.log(err)
})
// 通过getPromo方法 获取各类商品数据
this.getPromo("手机", "phoneList");//获取手机类的所有商品{},存入phoneList
this.getPromo("电视机", "miTvList");
this.getPromo("保护套", "protectingShellList");
this.getPromo("充电器", "chargerList");
// 通过getPromo方法 获取各类商品 **热门** 数据
this.getPromoh(
["电视机", "空调", "洗衣机"],
"applianceList"
);
this.getPromoh(
["保护套", "保护膜", "充电器", "充电宝"],
"accessoryList"
);
},
methods: {
// 获取家电模块 MyMenu子组件传过来的数据, 即激活项的切换
getChildMsg(val) { //MyMenu菜单项的激活状态
console.log(val) //slot 1/2
this.applianceActive = val;
},
// 获取配件模块子组件传过来的数据
getChildMsg2(val) {
this.accessoryActive = val;
},
getPromo(categoryName, val) {
// 有API传入时,例子
// categoryName:["电视机", "空调", "洗衣机"],
// val:"applianceList",
// api:"/goods/getHotProduct/"
// 判断是否有api传进来
console.log(categoryName) // 分类名称
console.log(val) // 数据变量名
// TODO 获取分类下商品和热门商品
this.$axios.get('goods/index/',{
params:{
// 'cate_id': 1
'cate_name': categoryName
}
}).then(res =>{
if (res.data.code == 200){
this[val] = res.data.goods
}
}).catch(err =>{
alert('页面出错了')
console.log(err)
})
},
getPromoh(categoryName, val){
this.$axios.post('/goods/how/',{'cate_name': categoryName})
.then(res =>{
if (res.data.code == 200){
this[val] = res.data.goods
}
}).catch(err =>{
alert('页面错误')
console.log(err)
})
}
}
};
</script>
<style scoped>
@import "../assets/css/index.css";
</style>