您现在的位置是: 网站首页 >Django >Vue+Django REST framework前后端分离生鲜电商 Django
【Vue+DRF生鲜电商】18.用户收藏、取消收藏商品接口实现
admin2019年5月30日 17:00 【Django | Vue 】 1201人已围观
Vue+Django REST framework前后端分离生鲜电商简介 Vue+Django REST framework 打造前后端分离的生鲜电商项目(慕课网视频)。 Github地址:https://github.com/xyliurui/DjangoOnlineFreshSupermarket ; Django版本:2.2、djangorestframework:3.9.2。 前端Vue模板可以直接联系我拿。
## 用户收藏接口实现 这个功能属于用户操作的功能,写在 user_operation 应用下 对于收藏功能,如果点击收藏,相当于是添加一条收藏记录(`mixins.CreateModelMixin`),如果是取消收藏,则删除收藏记录(`mixins.DestroyModelMixin`) ### 用户收藏接口基础 #### 用户添加收藏序列化 在 user_operation 应用下创建 serializers.py ,然后创建序列化类`UserFavSerializer`,用于序列化用户收藏数据 ```python from rest_framework import serializers from .models import UserFav class UserFavSerializer(serializers.ModelSerializer): class Meta: model = UserFav fields = ['user', 'goods'] ``` #### 用户收藏商品ViewSet 编辑 user_operation 中的 views.py ```python # apps/user_operation/views.py from rest_framework import viewsets, mixins from .serializers import UserFavSerializer from .models import UserFav class UserFavViewSet(mixins.CreateModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet): """ 用户收藏商品 取消收藏商品 """ queryset = UserFav.objects.all() serializer_class = UserFavSerializer ``` #### 用户收藏urls配置 修改主 urls.py ,添加收藏商品的router ```python from user_operation.views import UserFavViewSet router.register(r'userfavs', UserFavViewSet, base_name='userfavs') # 用户收藏商品 ``` 访问 http://127.0.0.1:8000/userfavs/ 可以看到下面内容 ![BLOG_20190530_170240_51](/media/blog/images/2019/05/BLOG_20190530_170240_51.png "博客图集BLOG_20190530_170240_51.png") 这里面用户和商品都可以自己选择。但实际上用户是不应该可选的,只需要获取当前登录用户。要收藏商品,只需要传递商品的对象即可。 所以就需要解决`UserFavSerializer`中的`user`如何填充当前用户。 #### 创建user隐藏字段 访问 https://www.django-rest-framework.org/api-guide/validators/#advanced-field-defaults 查看具体使用方法 在序列化器中跨多个字段应用的验证器有时可能需要一个字段输入,这个字段不应该由API客户机提供,但是可以作为验证器的输入。 可能想要使用两种模式来进行这种验证: - 使用`HiddenField`。该字段将出现在`validated_data`中,但序列化输出时不会显示出来,**可以用于设置当前登录用户**。 - 使用带有`read_only=True`的标准字段,但该字段也包含一个`default=…`参数。此字段将在序列化器输出表示中使用,但不能由用户直接设置。 REST框架包含一些缺省值,这些缺省值在此上下文中可能很有用。 **CurrentUserDefault** 可用于表示当前用户的默认类。为了使用它,在实例化序列化器时,`request`必须作为上下文字典的一部分提供。例如在本项目中 ```python # apps/user_operation/serializers.py class UserFavSerializer(serializers.ModelSerializer): user = serializers.HiddenField( default=serializers.CurrentUserDefault() # 表示user为隐藏字段,默认为获取当前登录用户 ) class Meta: model = UserFav fields = ['user', 'goods'] ``` 此时刷新 http://127.0.0.1:8000/userfavs/ 可以看到user字段已经隐藏了 ![BLOG_20190530_170227_67](/media/blog/images/2019/05/BLOG_20190530_170227_67.png "博客图集BLOG_20190530_170227_67.png") 如果选中一个商品,点击POST,这时候会向后台提交一个数据,但用户为隐藏提交的 ![BLOG_20190530_170221_76](/media/blog/images/2019/05/BLOG_20190530_170221_76.png "博客图集BLOG_20190530_170221_76.png") 这时候会返回一个`goods.id`,现在访问后台查看这条数据,就可以看到 ![BLOG_20190530_170213_66](/media/blog/images/2019/05/BLOG_20190530_170213_66.png "博客图集BLOG_20190530_170213_66.png") ### 取消收藏商品(删除数据) 一般情况在做serializer时,如果有删除操作,就需要将它的`id`返回回来 ```python # apps/user_operation/serializers.py class UserFavSerializer(serializers.ModelSerializer): user = serializers.HiddenField( default=serializers.CurrentUserDefault() # 表示user为隐藏字段,默认为获取当前登录用户 ) class Meta: model = UserFav fields = ['user', 'goods', 'id'] ``` 再来添加一条数据,就可以得到序列化中的id ![BLOG_20190530_170204_16](/media/blog/images/2019/05/BLOG_20190530_170204_16.png "博客图集BLOG_20190530_170204_16.png") 有了这个id,后期做删除功能,也就是取消收藏就简单了。 #### 列出所有收藏 在收藏商品ViewSet中,有了添加收藏,删除收藏,也可以有`mixins.ListModelMixin`显示收藏的功能 ```python # apps/user_operation/views.py class UserFavViewSet(mixins.CreateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet): """ 用户收藏商品 取消收藏商品 显示收藏商品 """ queryset = UserFav.objects.all() serializer_class = UserFavSerializer ``` 现在刷新 http://127.0.0.1:8000/userfavs/ ,可以看到所有收藏商品的序列化数据 ![BLOG_20190530_170156_44](/media/blog/images/2019/05/BLOG_20190530_170156_44.png "博客图集BLOG_20190530_170156_44.png") 现在获取的`goods`只是`id`,但有时候也需要商品的其他详情,这个在个人中心,显示商品收藏时完善。 删除操作url为,DEL /userfavs/id/ ,只需要删除对应收藏的指定id即可 #### 指定收藏记录的id执行DELETE 现在来删除id为1的收藏数据,利用工具实现,可以得到下面的204返回值,表明删除成功的。 ![BLOG_20190530_170144_36](/media/blog/images/2019/05/BLOG_20190530_170144_36.png "博客图集BLOG_20190530_170144_36.png") 刷新 http://127.0.0.1:8000/userfavs/ 可以看到,id为1的数据删除成功了。 ![BLOG_20190530_170133_74](/media/blog/images/2019/05/BLOG_20190530_170133_74.png "博客图集BLOG_20190530_170133_74.png") ### 收藏商品数据联合唯一性 用户反复点击收藏,会多次创建数据,这是不合理的,实际上用户点击收藏会创建一条收藏数据,用户再次点击一次,应该删除该条数据。 #### models中配置unique_together保证联合唯一 设置用户和商品对应联合唯一,当数据已存在时,数据库就会抛出异常 ```python # apps/user_operation/models.py class UserFav(models.Model): """ 用户收藏 """ user = models.ForeignKey(User, verbose_name='用户', help_text='用户', on_delete=models.CASCADE, related_name='favs') goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='商品', help_text='商品', related_name='favs') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '用户收藏' unique_together = ['user', 'goods'] def __str__(self): return "{} 收藏 {}".format(self.user.name if self.user.name else self.user.username, self.goods.name) ``` 设置完成后需要执行`makemigrations`和`migrate`,如果数据库中存在同样的,最后删除再执行 连续收藏一个商品2次,那么第一个就会抛出异常 ![BLOG_20190530_170123_15](/media/blog/images/2019/05/BLOG_20190530_170123_15.png "博客图集BLOG_20190530_170123_15.png") #### DRF配置UniqueTogetherValidator联合唯一 也可以自己在serializer中配置,访问 https://www.django-rest-framework.org/api-guide/validators/#uniquetogethervalidator 查看DRF配置。 在做这个之前,联合唯一也是可以实现的,因为在`UserFavSerializer`中使用的是`ModelSerializer`,类似于Django的`ModelForm`,它需要满足model中配置的条件,因为model中配置了`unique_together = ['user', 'goods']`,当提交的数据不满足就会抛出上图的异常。 实际上,DRF也是可以自定义的,`UniqueTogetherValidator`验证器可用于对模型实例强制`unique_together`约束。它有两个必需的参数和一个可选的消息参数: - `queryset`: required——这是应该强制惟一性的queryset。 - `fields`:required——字段名的列表或元组,应该构成一个惟一的集合。这些字段必须作为字段存在于序列化器类中。 - `message`:可选——验证失败时应该使用的错误消息。 在这个项目中可以如下使用 ```python # apps/user_operation/serializers.py from rest_framework import serializers from rest_framework.validators import UniqueTogetherValidator from .models import UserFav class UserFavSerializer(serializers.ModelSerializer): user = serializers.HiddenField( default=serializers.CurrentUserDefault() # 表示user为隐藏字段,默认为获取当前登录用户 ) class Meta: model = UserFav fields = ['user', 'goods', 'id'] # UserFav项目属于父列表,并且有一个由“position”字段定义的顺序。给定列表中的任何两项不得共享同一位置。 validators = [ UniqueTogetherValidator( queryset=UserFav.objects.all(), fields=('user', 'goods'), message='已经收藏' ) ] ``` 注意:`UniqueTogetherValidation`类总是施加一个隐式的约束,它所应用的所有字段总是按需要处理。具有默认值的字段是一个例外,因为它们总是提供一个值,即使在用户输入中省略了这个值。 以上`validators`不是作用域某个字段之上了,需要写在`Meta`中,因为`UniqueTogetherValidator`是作用域两个或两个字段以上的,不是针对一个字段,所以需要写在这。 现在在 http://127.0.0.1:8000/userfavs/ 页面POST相同商品,就会得到如下返回 ![BLOG_20190530_170114_89](/media/blog/images/2019/05/BLOG_20190530_170114_89.png "博客图集BLOG_20190530_170114_89.png") `non_field_errors`表示不能指定某一个字段的错误,而是多个字段造成的错误。可以在前端判断,如果出现`non_field_errors`字段,则表示整体的错误,不需要写在某个表单下面提示。
很赞哦! (0)
相关文章
文章交流
- emoji
当前用户
未登录,点击 登录专题目录
- 【Vue+DRF生鲜电商】01.课程结构介绍,开发环境搭建
- 【Vue+DRF生鲜电商】02.设置users、goods、trade、user_operation数据库并导入原始数据
- 【Vue+DRF生鲜电商】03.Restful API基础
- 【Vue+DRF生鲜电商】04.Vue项目结构介绍
- 【Vue+DRF生鲜电商】05.商品列表序列化普通方法
- 【Vue+DRF生鲜电商】06.DRF环境配置,使用Serializer类序列化商品列表
- 【Vue+DRF生鲜电商】07.序列化商品分页功能
- 【Vue+DRF生鲜电商】08.ViewSets & Routers显示商品列表
- 【Vue+DRF生鲜电商】09.使用DRF的filter过滤商品列表
- 【Vue+DRF生鲜电商】10.商品分类层级获取,Vue跨域请求商品分类
- 【Vue+DRF生鲜电商】11.Vue展示左侧分类、面包屑、排序、商品列表、分页
- 【Vue+DRF生鲜电商】12.用户登录之DRF Token认证登录原理和使用方法
- 【Vue+DRF生鲜电商】13.JWT用户认证原理配置,Vue登录接口调试
- 【Vue+DRF生鲜电商】14.用户注册发送短信验证码、登录字段验证
- 【Vue+DRF生鲜电商】15.用户注册使用信号量实现密码加密
- 【Vue+DRF生鲜电商】16.Vue中注册、退出功能交互
- 【Vue+DRF生鲜电商】17.DRF实现商品详情及热卖商品接口,Vue中显示商品详情和热卖
- 【Vue+DRF生鲜电商】18.用户收藏、取消收藏商品接口实现
- 【Vue+DRF生鲜电商】19.用户添加、删除收藏权限处理,根据商品id显示收藏,在Vue中实现收藏功能
- 【Vue+DRF生鲜电商】20.使用DRF自动生成文档的功能
- 【Vue+DRF生鲜电商】21.用户中心个人资料的展示,并在Vue中实现个人资料更新
- 【Vue+DRF生鲜电商】22.个人中心显示用户收藏功能,对收藏进行删除
- 【Vue+DRF生鲜电商】23.个人中心用户留言功能
- 【Vue+DRF生鲜电商】24.用户收货地址功能
- 【Vue+DRF生鲜电商】25.商品添加购物车接口功能,Vue和购物车联调
- 【Vue+DRF生鲜电商】26.使用Pycharm远程代码调试服务器Django代码
- 【Vue+DRF生鲜电商】26.订单接口功能,Vue和订单接口联调
- 【Vue+DRF生鲜电商】27.支付宝公钥,私钥,沙箱环境配置
- 【Vue+DRF生鲜电商】28.支付宝支付接口类解读,支付逻辑编辑
- 【Vue+DRF生鲜电商】29.线上服务支付宝接口和Vue联调,Django代理Vue运行
- 【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能
- 【Vue+DRF生鲜电商】31.首页商品按分类显示推荐功能
- 【Vue+DRF生鲜电商】32.商品操作后计数更改,热搜榜关键字功能实现
- 【Vue+DRF生鲜电商】33.数据缓存、接口访问限速功能
- 【Vue+DRF生鲜电商】34.第三方登录(微博、qq和微信)之微博登录登录测试
- 【Vue+DRF生鲜电商】35.使用social-app-django集成第三方登录