【Vue+DRF生鲜电商】22.个人中心显示用户收藏功能,对收藏
专题:Vue+Django REST framework前后端分离生鲜电商
Vue+Django REST framework 打造前后端分离的生鲜电商项目(慕课网视频)。
Github地址:https://github.com/xyliurui/DjangoOnlineFreshSupermarket ;
Django版本:2.2、djangorestframework:3.9.2。
更多内容请点击 我的博客 查看,欢迎来访。
用户收藏显示功能
在前面已经写好了用户收藏和取消收藏商品的功能,访问 http://127.0.0.1:8000/userfavs/ 即可看到,但收藏的商品只显示了商品的id
![](https://img.haomeiwen.com/i5730845/4864c9bf8c4139f6.png)
序列化收藏的商品UserFavListSerializer
没有显示商品的具体信息,首先还得做序列化。直接使用商品已做好的序列化类,也可以自己写,只显示所需要的信息。
# apps/user_operation/serializers.py
from goods.serializers import GoodsSerializer
class UserFavListSerializer(serializers.ModelSerializer):
goods = GoodsSerializer()
class Meta:
model = UserFav
fields = ['goods', 'id']
由于收藏商品和显示用户已收藏的商品使用了不同的序列化类,则也需要用到动态Serializer
动态使用序列化类UserFavViewSet
当显示用户的收藏时,使用上面的序列化类
# apps/user_operation/views.py
class UserFavViewSet(mixins.CreateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
"""
create:
用户收藏商品
destroy:
取消收藏商品
list:
显示收藏商品列表
retrieve:
根据商品id显示收藏详情
"""
queryset = UserFav.objects.all()
# serializer_class = UserFavSerializer
def get_serializer_class(self):
"""
不同的action使用不同的序列化
:return:
"""
if self.action == 'list':
return UserFavListSerializer # 显示用户收藏列表序列化
else:
return UserFavSerializer
permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
authentication_classes = (JWTAuthentication, SessionAuthentication) # 配置登录认证:支持JWT认证和DRF基本认证
lookup_field = 'goods_id'
def get_queryset(self):
# 过滤当前用户的收藏记录
return self.queryset.filter(user=self.request.user)
现在刷新 http://127.0.0.1:8000/userfavs/ 即可显示用户收藏商品的列表
![](https://img.haomeiwen.com/i5730845/e76de39bf57bee59.png)
同时商品的详情也被序列化。
Vue中显示收藏列表
当组件创建时调用getCollection()
// src/views/member/collection.vue
getCollection() { //获取收藏列表
getAllFavs().then((response) => {
this.collections = response.data;
}).catch(function (error) {
console.log(error);
});
},
之后调用getAllFavs
函数,请求接口获取用户的所有收藏
// src/api/api.js
//显示收藏列表
export const getAllFavs = () => {
return axios.get(`${local_host}/userfavs/`)
};
获取到数据之后,赋值给collections
,之后遍历显示到html中
<!-- src\views\member\collection.vue -->
<tr v-for="(item,index) in collections">
<td bgcolor="#ffffff">
<router-link :to="'/app/home/productDetail/'+item.goods.id" class="f6" target="_blank">{{item.goods.name}}</router-link>
</td>
<td bgcolor="#ffffff">本店价<span class="goods-price">¥{{item.goods.shop_price}}元</span>
</td>
<td align="center" bgcolor="#ffffff">
<a class="f6" @click="deletePro(index, item.goods.id)">删除</a>
</td>
</tr>
访问 http://127.0.0.1:8080/#/app/home/member/collection 可以查看用户收藏的商品列表
![](https://img.haomeiwen.com/i5730845/4074db6f24bdbee8.png)
从收藏夹删除商品
当用户点击收藏商品后面的删除时,传递的参数为item.goods.id
即商品的id
,因为在后端 apps/user_operation/views.py 的UserFavViewSet()
定义了有个属性叫lookup_field = 'goods_id'
,表示搜索的字段为goods
的id
<!-- src/views/member/collection.vue -->
<td align="center" bgcolor="#ffffff">
<a class="f6" @click="deletePro(index, item.goods.id)">删除</a>
</td>
会调用删除商品的函数deletePro()
// src/views/member/collection.vue
deletePro(index, id) { //删除收藏商品
// alert('您确定要从收藏夹中删除选定的商品吗?');
let msg = "您确定要从收藏夹中删除选定的商品吗?\n\n请确认!";
if (confirm(msg) === true) {
delFav(id).then((response) => {
this.collections.splice(index, 1);
alert('已删除商品');
}).catch(function (error) {
console.log(error);
});
return true;
} else {
return false;
}
}
![](https://img.haomeiwen.com/i5730845/848ba7aed2c822a5.png)
如果点击确认,会请求删除商品的接口,也就是取消商品收藏
// src/api/api.js
//取消收藏
export const delFav = goodsId => {
return axios.delete(`${local_host}/userfavs/` + goodsId + '/')
};