模型类:
from django.db import models
# Create your models here.
# 商品类别 例如:水果
class Category(models.Model):
cat_name = models.CharField('类别名称', max_length=20)
img = models.CharField('图片', max_length=200, default="")
class Meta:
verbose_name_plural = '类别名称'
db_table = 'Category'
def __str__(self):
return self.cat_name
# 类别名下的各类水果
class GoodsImage(models.Model):
name = models.CharField('商品名称', max_length=20)
img = models.CharField('图片', max_length=200)
price = models.DecimalField('价格', decimal_places=2, max_digits=8)
cat = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name='商品类别')
class Meta:
verbose_name_plural = '商品名称'
db_table = 'GoodsImage'
def __str__(self):
return self.name
# 某种水果的详情信息
class GoodData(models.Model):
sku_name = models.CharField('商品名', max_length=50)
price = models.DecimalField('商品价格', max_digits=9, decimal_places=2)
selling_price = models.DecimalField('商品销售价格', max_digits=9, decimal_places=2)
img = models.CharField('商品默认图片', max_length=200)
title = models.CharField('商品标题', max_length=30, null=True)
instruction = models.TextField('商品描述')
count = models.IntegerField('商品销售数量', default=0)
stock = models.IntegerField('商品库存数量', default=0)
goodsimage = models.ForeignKey(GoodsImage, on_delete=models.CASCADE, verbose_name='水果名称')
online = models.BooleanField('是否在售', default=True)
class Meta:
db_table = 'GoodData'
verbose_name_plural = '商品信息'
def __str__(self):
return self.sku_name
# 详情页轮播图
class GoodsLbt(models.Model):
img = models.CharField('图片', max_length=200)
describe = models.CharField('描述', max_length=200)
gooddata = models.ForeignKey(GoodData, on_delete=models.CASCADE, verbose_name='商品信息表')
class Meta:
db_table = 'GoodsLbt'
verbose_name_plural = '轮播图'
def __str__(self):
return self.describe
序列化器:
from rest_framework import serializers
from goods.models import Category, GoodsImage, GoodData, GoodsLbt
class SerCategory(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
class SerGoodsImage(serializers.ModelSerializer):
class Meta:
model = GoodsImage
fields = '__all__'
class SerGoodsData(serializers.ModelSerializer):
name = serializers.SerializerMethodField(read_only=True)
def get_name(self, obj):
return obj.goodsimage.name
class Meta:
model = GoodData
fields = '__all__'
class SerGoodsLbt(serializers.ModelSerializer):
class Meta:
model = GoodsLbt
fields = '__all__'
视图功能:
from django.shortcuts import render
# Create your views here.
from rest_framework.response import Response
from rest_framework.views import APIView
from goods.models import Category, GoodData, GoodsImage
from goods.serializers import SerCategory, SerGoodsImage, SerGoodsData, SerGoodsLbt
# 获取类别名
class GetCategory(APIView):
def get(self, request):
catimg = Category.objects.filter(id=1)
ser_img = SerCategory(catimg, many=True)
return Response({
'code': 200,
'msg': '种类信息获取成功',
'data': ser_img.data
})
# 获取类别名下的水果
class GetGoodsImage(APIView):
def get(self, request):
cat_name = request.query_params.get('catName')
try:
# cat_data = Category.objects.filter(cat_name=cat_name).first()
cat_data = Category.objects.get(cat_name=cat_name)
except:
return Response({
'msg': '此类商品不存在',
'code': 204
})
goods_data = cat_data.goodsimage_set.all()
ser = SerGoodsImage(goods_data, many=True)
return Response({
'code': 200,
'msg': '成功获取商品信息',
'res': ser.data
})
# 获取某种水果的详情信息
class GoodXq(APIView):
def get(self, request):
good_id = request.query_params.get('NameId')
# try:
good_cl = GoodsImage.objects.get(id=good_id)
good_data = good_cl.gooddata_set.all()
# 此方法功用的是GoodData表中的id 虽然效果一样,不过是添加数据库时的顺序巧合
# good_data = GoodData.objects.filter(id=good_id).all()
# except:
# return Response({
# 'code': 204,
# 'msg:': '商品不存在1'
# })
ser = SerGoodsData(good_data, many=True)
return Response(ser.data)
# 详情页轮播图
class GoodLbt(APIView):
def get(self, request):
good_id = request.query_params.get('NameId')
good_cl = GoodData.objects.get(id=good_id)
lbt = good_cl.goodslbt_set.all()
ser_lbt = SerGoodsLbt(lbt, many=True)
return Response({
'code': 200,
'msg': '轮播图加载成功',
'goodlbt': ser_lbt.data
})
##热门商品后端逻辑(本篇未用到)
##P5商城项目 供参考
# 获取热门商品
class HotProduct(APIView):
def get(self, request):
cate_list = request.query_params.getlist("categoryName[]")
# 获取种类信息
cate_data_list = []
for i in cate_list:
cate_data = Category.objects.get(cate_name=i)
cate_data_list.append(cate_data)
# 根据类别信息 获取 商品信息
goods_data_list = []
for i in cate_data_list:
goods_data_list.append(i.goods_set.all())
# 将商品信息合并
goods_data_queryset = reduce((lambda x, y: x | y), goods_data_list).order_by("-count")
# 序列化
ser = GoodsSer(goods_data_queryset, many=True)
return Response({
"code": 200,
"msg": "成功获取热门商品信息",
"result": ser.data
})
路由:
from django.urls import path
from goods import views
urlpatterns = [
path('images/', views.GetGoodsImage.as_view()),
path('cimages/', views.GetCategory.as_view()),
path('goodxq/', views.GoodXq.as_view()),
path('goodlbt/', views.GoodLbt.as_view()),
]
前端vue:#############
水果分类页面:
<template>
<div>
<el-tabs v-model="gf">
<el-tab-pane label="新鲜水果" name="first">
<div class="aa">
<div class="gg">
<img :src="catedata" alt="aaa" width="150px" height="220px">
<!-- <el-avatar shape="square" :src="catedata"></el-avatar> -->
</div>
<div v-for="i, j in FruitData" :key="j">
<div>{{ i.name }}</div>
<div>
<router-link :to="{ name: 'GoodXq', params: { goodid: i.id } }">
<img :src="i.img" alt="aaa">
</router-link>
</div>
<div class="hh">¥ {{ i.price }}</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="盒装草莓" name="second">盒装草莓</el-tab-pane>
<el-tab-pane label="柠檬" name="third">柠檬</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: '',
data() {
return {
imgHost: "http://127.0.0.1:8000",
shuiguoList: '', //水果商品列表
categoryName: '水果',
FruitData: [],
gf: "first",
img: "",
catedata: '',
};
},
props: {},
components: {},
created() { },
mounted() {
this.getPromo()
this.getcat()
},
methods: {
getcat() {
axios.get('/goods/cimages/')
.then((resp) => {
console.log(resp)
this.catedata = resp.data.data[0].img
}).catch((err) => {
console.log(err)
});
},
getPromo() {
axios
.get('/goods/images/', {
params: { catName: this.categoryName },
})
.then(res => {
console.log("@@获取" + this.categoryName + "的响应", res)
//获取属性,并赋值,如'phoneList'
// this.shuiguoList = res.data.res;
this.FruitData = res.data.res
console.log(this.FruitData);
})
.catch(err => {
console.log(err);
});
},
},
computed: {},
watch: {},
directives: {},
filters: {}
};
</script>
<style scoped >
.aa {
display: flex;
justify-content: space-between;
width: 20%;
}
.hh {
color: red;
}
</style>
# 跳转水果详情页
<template>
<div class="big">
<div class="left">
<el-carousel alt="aaa" class="img">
<el-carousel-item v-for="(item,i) in goodlbtlist" :key="i">
<!-- <h3 class="small">{{ item }}</h3> -->
<img :src="item.img" width="400px" height="450px">
</el-carousel-item>
</el-carousel>
</div>
<div class="right" v-for="(item, i) in goodxqlist" :key="i">
<div class="name">{{ item.sku_name }}</div>
<div class="is">{{ item.instruction }}</div>
<!-- <div class="title">title</div> -->
<div class="cate">{{ item.name }}</div>
<div class="price">{{ item.price }}</div>
<div>
<div class="red">
<div>{{ item.title }}</div>
<div>{{ item.price }}</div>
</div>
<div class="hh">
<i class="el-icon-remove"></i>
{{ item.selling_price }}
<i class="el-icon-circle-plus"></i>
</div>
<div class="ii">
<router-link :to="{ name: 'Register' }">
<button>加入购物车</button>
</router-link>
<!-- <el-button class="btn1" @click="jia">加入购物车</el-button>
<el-button class="btn2" @click="jia2">喜欢</el-button> -->
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: '',
data() {
return {
NameId: this.$route.params.goodid, //商品id
goodxqlist: {}, //单个商品信息
img: '',
goodlbtlist: {}, //单个商品轮播图
};
},
props: {},
components: {},
created() { },
mounted() {
this.goodXq()
this.goodlbt()
},
methods: {
jia2() {
this.$message({
message: "加入收藏!",
type: "warning"
})
},
jia() {
this.$message({
message: "加入购物车成功",
type: "warning"
})
},
goodXq() {
axios.get('/goods/goodxq/', {
params: { NameId: this.NameId }
})
.then((resp) => {
console.log(resp)
this.goodxqlist = resp.data
this.img = resp.data[0].img
}).catch((err) => {
console.log(err)
});
},
goodlbt() {
axios.get('/goods/goodlbt/', { params: { NameId: this.NameId } })
.then((resp) => {
console.log(resp)
this.goodlbtlist = resp.data.goodlbt
}).catch((err) => {
console.log(err)
});
}
},
computed: {},
watch: {},
directives: {},
filters: {}
};
</script>
<style scoped>
.btn2 {
background-color: rgb(131, 129, 129);
color: white;
width: 40%;
height: 30%;
}
.img {
width: 400px;
height: 450px;
}
.ii {
padding-top: 5%;
display: flex;
}
.btn1 {
width: 50%;
height: 30%;
background-color: rgb(225, 96, 27);
color: white;
}
.red {
display: flex;
}
.cate {
color: coral;
padding-bottom: 4%;
}
.hh {
color: rgb(252, 190, 190);
}
.price {
color: coral;
padding-bottom: 5%;
}
.is {
font-size: 10px;
color: rgb(143, 166, 185);
padding-bottom: 2%;
}
.name {
font-size: 22px;
/* width: 40%; */
padding-bottom: 2%;
}
.left {
width: 30%;
height: 500px;
}
.right {
width: 55%;
}
.big {
display: flex;
padding: 5%;
}
</style>