商品详情功能
后端
商品详情及商品轮播图实现
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView
from goods.models import Categroy,Goods
from goods.serializers import Goodsser
import redis
#商品详情视图
class Goodsinfoview(APIView):
def get(self,request,goods_id):
#从数据库获取商品
goods_info=Goods.objects.filter(id=goods_id).first()
# 判断数据库是否存在
if not goods_info:
return Response({
'code':400,
'msg':'商品不存在'
})
#走到这一步说明商品存在
#序列化
ser=Goodsser(instance=goods_info,many=False)
return Response({
'code':200,
'msg':'商品获取成功',
'goods':ser.data
})
#商品轮播图视图
class Goodsinfoimagesview(APIView):
def get(self,request,goods_id):
goods_info=Goods.objects.filter(id=goods_id).first()
if not goods_info:
return Response({
'code':400,
'msg':'商品不存在'
})
goods_images=goods_info.goodsimages_set.all()
print(goods_images)
#手动序列化,把query_set格式的数据转换为list或者dict格式的数据
img_all=[]
for i in goods_images:
img_all.append({
'img_path':i.img,
'title':i.title
})
return Response({
'code':200,
'msg':'轮播图获取成功',
'imgs':img_all,
})
配置路由
from django.urls import path
from goods import views
urlpatterns = [
path('info/<int:goods_id>/',views.Goodsinfoview.as_view()),#获取商品详情
path('info/images/<int:goods_id>/',views.Goodsinfoimagesview.as_view()), #商品轮播图
]
前端
商品详情及商品轮播图实现
找到功能所在的vue文件 :例如Details.vue
< template>< /template>里的
展示数据的函数要跟后端保持一致
data() {
return {
dis: false, // 控制“加入购物车 按钮 是否可用”
productID: "", // router-link 传入的商品id
productPicture: "", // 商品图片
goodsinfo:'' //商品详情
};
watch: {
// 监听商品id的变化,请求后端获取商品数据
productID: function (val) {//val 为变化的新值
console.log("===商品ID变化,当前为:", val)
// TODO 获取商品详情
this.$axios.get('/goods/info/'+val+'/').then((result) => {
if (result.data.code==200){
//goods是后端传递的值
this.goodsinfo=result.data.goods
}else{
this.notifyError(result.data.msg)
}
}).catch((err) => {
console.log(err)
});
// TODO 获取商品轮播图
this.$axios.get('/goods/info/images/'+val+'/').then((result) => {
if (result.data.code==200){
this.productPicture=result.data.imgs
}else{
this.notifyError(result.data.msg)
}
}).catch((err) => {
console.log(err)
});
}
浏览记录及商品收藏功能实现
后端
验证登录的中间件
在django项目根目录创建一个middleware文件夹
在文件夹内创建LoginMiddleware.py文件
在文件内编写中间件
from django.utils.deprecation import MiddlewareMixin
import jwt,time
from django.conf import settings
#定义检测用户登录的中间件
class CheckUser(MiddlewareMixin):
#请求响应前调用
def process_request(self,request):
print('我是检测登录的中间件')
#获取前台用户发送请求header头里面的token字段
token=request.META.get('HTTP_TOKEN')
print('token',token)
try:
#对token进行解码
user=jwt.decode(token,key=settings.SECRET_KEY,algorithms='HS256')
if user['exp']<int(time.time()): #如果用户已经过期则为空
user=None
except Exception as a:
print(a)
#解码失败,user信息为空
user=None
#把解析出来的user信息,通过request的形式再次传入实体的request里面
request.META['USER']=user
在settings里注册中间件
MIDDLEWARE = [
...
'middleware.LoginMiddleware.CheckUser',
...
]
历史浏览记录及 添加 删除 查看商品收藏。功能的实现
from rest_framework.response import Response
from rest_framework.views import APIView
from goods.models import Categroy,Goods
from goods.serializers import Goodsser
import redis
#历史浏览记录视图
class Historyview(APIView):
def post(self,request,goods_id):
#通过检测用户登录中间件给user数据
user = request.META.get('USER')
if not user:
return Response({
'code':400,
'msg':'用户未登录1'
})
print(user)
user_id=user['user_id'] #拿到了当前用户的id
#判断一下商品是否存在
goods_info=Goods.objects.filter(id=goods_id).first()
if not goods_info:
return Response({
'code':400,
'msg':'商品不存在'
})
#把浏览记录存到数据库
r=redis.Redis(host='127.0.0.1',port=6379,password='shayebushi')
#分析历史记录,使用list比较合适[5,6,1,4,2]
key='history:'+str(user_id) #3 history;3
r.lrem(key,0,goods_id) #先从历史记录移除
r.lpush(key,goods_id) #再添加到redis数据库
r.ltrim(key,0,4) #截取最近的五条记录
return Response({
'code':200,
'msg':'历史记录添加成功,商品名'+goods_info.sku_name
})
#添加商品收藏视图
class Addlikeview(APIView):
def post(self,request,goods_id):
# 通过检测用户登录中间件给user数据
user=request.META.get('USER')
if not user:
return Response({
'code':400,
'msg':'用户未登录'
})
user_id=user['user_id'] #拿到登陆账户的id
goods_info=Goods.objects.filter(id=goods_id).first()
if not goods_info:
return Response({
'code':400,
'msg':'商品不存在'
})
r=redis.Redis(host='127.0.0.1',port=6379,password='shayebushi')
key='like:'+str(user_id) #like: 3
#判断,goods_id是否已经存在数据库
like_goods=r.smembers(key)
goods_ids=[]
for i in like_goods:
goods_ids.append(i.decode())
if str(goods_id)in goods_ids:
return Response({
'code':400,
'msg':'已收藏,不用重复收藏'
})
r.sadd(key,goods_id)
return Response({
'code':200,
'msg':'添加收藏成功'
})
#查看收藏视图
class Showlikeview(APIView):
def get(self,request):
# 通过检测用户登录中间件给user数据
user = request.META.get('USER')
if not user:
return Response({
'code': 400,
'msg': '用户未登录'
})
user_id = user['user_id'] #拿到登陆账户的id
#链接数据库
r = redis.Redis(host='127.0.0.1', port=6379, password='shayebushi')
key = 'like:' + str(user_id) # like: 3
like_goods=r.smembers(key)
goods_ids=[]
for i in like_goods:
goods_ids.append(i.decode())
# goods_ids就是收藏的商品id
#通过goods_ids 查询所有商品信息
goods_all=Goods.objects.filter(id__in=goods_ids).all()
# 序列化
ser=Goodsser(instance=goods_all,many=True)
return Response({
'code':200,
'msg':'收藏商品获取成功',
'goods':ser.data
})
#删除收藏视图
class Deletelikeview(APIView):
def post(self,request,goods_id):
# 通过检测用户登录中间件给user数据
user = request.META.get('USER')
if not user:
return Response({
'code': 400,
'msg': '用户未登录'
})
user_id = user['user_id'] #拿到登陆账户的id
# 链接数据库
r = redis.Redis(host='127.0.0.1', port=6379, password='shayebushi')
key = 'like:' + str(user_id) # like: 3
like_goods=r.smembers(key)
goods_ids=[]
for i in like_goods:
goods_ids.append(i.decode())
if str(goods_id) not in goods_ids:
return Response({
'code':400,
'msg':'没有收藏过'
})
r.srem(key,goods_id)
return Response({
'code':200,
'msg':'删除成功'
})
配置路由
from django.urls import path
from goods import views
urlpatterns = [
path('history/<int:goods_id>/',views.Historyview.as_view()), #历史浏览记录
path('add/like/<int:goods_id>/',views.Addlikeview.as_view()), #添加收藏
path('show/like/',views.Showlikeview.as_view()), #查看收藏
path('delete/like/<int:goods_id>/',views.Deletelikeview.as_view()) #删除收藏
]
前端
历史浏览记录及 添加 删除 查看商品收藏。功能的实现
找到功能所在的vue文件 :例如Details.vue,Collect.vue,MyList.vue
展示数据的函数要跟后端保持一致
历史浏览记录及 添加收藏 :Details.vue
注意:this.$axios.post(路由,{},{})第3个才是teaders
this. $axios.get(路由,{})第2个才是teaders
watch: {
// TODO 添加到历史记录
this.$axios.post('/goods/history/'+val+'/',{},{
'headers':{
'token':localStorage.getItem('token')
}
}).then((result) => {
console.log('添加历史记录结束,请求体',result)
}).catch((err) => {
console.log('添加历史记录失败,错误信息',err)
});
}
methods: {
addCollect() {
// 判断是否登录,没有登录则显示登录组件
if (!this.$store.getters.getUser) {
this.$store.dispatch("setShowLogin", true);
return;
}
console.log("把商品加入收藏,商品ID:", this.productID)
// TODO 加入收藏////////
this.$axios.post('/goods/add/like/'+this.productID+'/',{},{
'headers':{
'token':localStorage.getItem('token')
}
}).then((result) => {
if (result.data.code==200){
this.notifySucceed(result.data.msg)
}else{
this.notifyError(result.data.msg)
}
}).catch((err) => {
console.log(err)
});
}
}
获取/查看收藏的商品 :Collect.vue
activated() {
//TODO 获取收藏数据
this.$axios.get('/goods/show/like/',{
'headers':{
'token':localStorage.getItem('token')
}
}).then((result) => {
if (result.data.code==200){
this.collectList=result.data.goods
}else{
this.notifyError(result.data.msg)
}
}).catch((err) => {
console.log(err)
});
}
删除收藏商品 :MyList.vue
methods: {
deleteCollect(product_id) {
// TODO 删除收藏
console.log("删除收藏的商品,ID", product_id)
this.$axios.post('/goods/delete/like/'+product_id+'/',{},{
'headers':{
'token':localStorage.getItem('token')
}
}).then((result) => {
if (result.data.code==200){
for (var i=0;i<this.list.length;i++){
var item=this.list[i]
if (item.id==product_id){
this.list.splice(i,1)
}
}
this.notifySucceed(result.data.msg)
}else{
this.notifyError(result.data.msg)
}
}).catch((err) => {
console.log(err)
});
}