您现在的位置是: 网站首页 >Django >Vue+Django REST framework前后端分离生鲜电商 Django

【Vue+DRF生鲜电商】24.用户收货地址功能

admin2019年6月29日 22:07 Django | Html | Vue 220人已围观

Vue+Django REST framework前后端分离生鲜电商简介 Vue+Django REST framework 打造前后端分离的生鲜电商项目(慕课网视频)。 Github地址:https://github.com/xyliurui/DjangoOnlineFreshSupermarket ; Django版本:2.2、djangorestframework:3.9.2。 前端Vue模板可以直接联系我拿。

## 用户收货地址功能 对于收货地址,需要实现收货地址的增、删、改、查,所以需要继承的类有`mixins.ListModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet`,而这些类也可以合并为一个`viewsets.ModelViewSet`,点击去就可以看到继承关系: ![BLOG_20190629_221125_50](/media/blog/images/2019/06/BLOG_20190629_221125_50.png "博客图集BLOG_20190629_221125_50.png") ### 用户收货地址视图AddressViewSet 编辑 apps/user_operation/views.py ```python class AddressViewSet(viewsets.ModelViewSet): """ 收货地址管理 list: 获取收货地址 create: 添加收货地址 update: 更新收货地址 delete: 删除收货地址 """ permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) # 用户必须登录才能访问 authentication_classes = (JWTAuthentication, SessionAuthentication) # 配置登录认证:支持JWT认证和DRF基本认证 ``` `permission_classes`和`authentication_classes`直接复制上面的即可,因为也需要用户登录认证才能完成的。 ### 用户收货地址序列化AddressSerializer 在前端上,用户的收货地址分为省市区 ![BLOG_20190629_221116_22](/media/blog/images/2019/06/BLOG_20190629_221116_22.png "博客图集BLOG_20190629_221116_22.png") 而之前我们定义的models中定义是不够的,原来的models为: ```python class UserAddress(models.Model): """ 用户收货地址 """ user = models.ForeignKey(User, verbose_name='用户', help_text='用户', on_delete=models.CASCADE, related_name='addresses') district = models.CharField(max_length=100, default='', verbose_name='区域', help_text='区域') address = models.CharField(max_length=200, default='', verbose_name='收货地址', help_text='收货地址') signer_name = models.CharField(max_length=20, default='', verbose_name='签收人', help_text='签收人') signer_mobile = models.CharField(max_length=11, verbose_name='联系电话', help_text='联系电话') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '收货地址' def __str__(self): return self.address ``` 所以需要进行修改,添加`province`和`city`两个字段 ```python class UserAddress(models.Model): """ 用户收货地址 """ user = models.ForeignKey(User, verbose_name='用户', help_text='用户', on_delete=models.CASCADE, related_name='addresses') province = models.CharField(max_length=100, default='', verbose_name='省份', help_text='省份') city = models.CharField(max_length=100, default='', verbose_name='城市', help_text='城市') district = models.CharField(max_length=100, default='', verbose_name='区域', help_text='区域') address = models.CharField(max_length=200, default='', verbose_name='收货地址', help_text='收货地址') signer_name = models.CharField(max_length=20, default='', verbose_name='签收人', help_text='签收人') signer_mobile = models.CharField(max_length=11, verbose_name='联系电话', help_text='联系电话') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '收货地址' def __str__(self): return self.address ``` 添加完成后一定要执行`makemigrations`和`migrate`。 编写收货地址序列化类,编辑 apps/user_operation/serializers.py 添加 ```python from .models import UserFav, UserLeavingMessage, UserAddress class AddressSerializer(serializers.ModelSerializer): user = serializers.HiddenField( default=serializers.CurrentUserDefault() # 表示user为隐藏字段,默认为获取当前登录用户 ) class Meta: model = UserAddress fields = ('id', 'user', 'province', 'city', 'district', 'address', 'signer_name', 'signer_mobile') ``` ### 完善用户收货地址视图AddressViewSet 添加序列化类`AddressSerializer` ```python from .serializers import UserFavSerializer, UserFavListSerializer, UserLeavingMessageSerializer, AddressSerializer from .models import UserFav, UserLeavingMessage, UserAddress class AddressViewSet(viewsets.ModelViewSet): """ 收货地址管理 list: 获取收货地址 create: 添加收货地址 update: 更新收货地址 delete: 删除收货地址 """ permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) # 用户必须登录才能访问 authentication_classes = (JWTAuthentication, SessionAuthentication) # 配置登录认证:支持JWT认证和DRF基本认证 queryset = UserAddress.objects.all() serializer_class = AddressSerializer def get_queryset(self): return self.queryset.filter(user=self.request.user) ``` ### 注册收货地址url 编辑 DjangoOnlineFreshSupermarket/urls.py ,注册`address`这个url ```python from user_operation.views import UserFavViewSet, UserLeavingMessageViewSet, AddressViewSet router.register(r'address', AddressViewSet, base_name='address') # 用户收货地址 ``` 查看Server是否已经重启。 ### DRF Docs中测试address功能 访问 http://127.0.0.1:8000/docs/#address 可以看到新增的API ![BLOG_20190629_221104_70](/media/blog/images/2019/06/BLOG_20190629_221104_70.png "博客图集BLOG_20190629_221104_70.png") 在`create`中创建一个收货地址 ![BLOG_20190629_221058_96](/media/blog/images/2019/06/BLOG_20190629_221058_96.png "博客图集BLOG_20190629_221058_96.png") 添加完信息后,点击Send Request,就可以在右上角看到返回的数据 在`list`中点击Send Request就可以看到返回的列表信息 ![BLOG_20190629_221050_36](/media/blog/images/2019/06/BLOG_20190629_221050_36.png "博客图集BLOG_20190629_221050_36.png") ### Vue中收货地址接口联调 api放在 src/api/api.js 中 ```JavaScript //添加收货地址 export const addAddress = params => { return axios.post(`${local_host}/address/`, params) }; //删除收货地址 export const delAddress = addressId => { return axios.delete(`${local_host}/address/` + addressId + '/') }; //修改收货地址 export const updateAddress = (addressId, params) => { return axios.patch(`${local_host}/address/` + addressId + '/', params) }; //获取收货地址 export const getAddress = () => { return axios.get(`${local_host}/address/`) }; ``` Vue收获地址管理的页面在 src/views/member/receive.vue 中 当进入这个组件后,会调用`getReceiveInfo()` ```JavaScript created() { this.getReceiveInfo(); }, ``` 然后调用`getAddress()`,也就是请求`getAddress`的api ```JavaScript getReceiveInfo() { //获取收件人信息 getAddress().then((response) => { //console.log(response.data); this.receiveInfoArr = response.data; }).catch(function (error) { console.log(error); }); }, ``` 获取到数据之后,传递给`receiveInfoArr`,然后遍历得到所有地址列表 ```html <table width="100%" border="0" cellpadding="5" cellspacing="1" bgcolor="#dddddd" v-for="(item, index) in receiveInfoArr"> <tbody> <tr> <td align="right" bgcolor="#ffffff">配送区域:</td> <td colspan="3" align="left" bgcolor="#ffffff"> <div class="addr" @click="bubble(index)"> <v-distpicker :province="item.province" :city="item.city" :area="item.district" @province="updateProvince" @city="updateCity" @area="updateArea"></v-distpicker> </div> </td> </tr> <tr> <td align="right" bgcolor="#ffffff">收货人姓名:</td> <td align="left" bgcolor="#ffffff"><input name="consignee" type="text" class="inputBg" id="consignee_0" value="ssss" v-model="item.signer_name"> <span :class="{error:item.signer_name==''}">(必填)</span> </td> </tr> <tr> <td align="right" bgcolor="#ffffff">详细地址:</td> <td align="left" bgcolor="#ffffff"><input name="address" type="text" class="inputBg" id="address_0" v-model="item.address"> <span :class="{error:item.address==''}">(必填)</span></td> </tr> <tr> <td align="right" bgcolor="#ffffff">手机:</td> <td align="left" bgcolor="#ffffff"><input name="mobile" type="text" class="inputBg" id="mobile_0" v-model="item.signer_mobile"><span :class="{error:item.signer_mobile==''}">(必填)</span></td> </tr> <tr> <td align="right" bgcolor="#ffffff">&nbsp;</td> <td colspan="3" align="center" bgcolor="#ffffff"> <button class="bnt_blue_2" @click="confirmUpdate(item.id, index)">确定修改</button> <button class="bnt_blue_2" @click="deleteInfo(item.id)">删除</button> </td> </tr> </tbody> </table> ``` 访问 http://127.0.0.1:8080/#/app/home/member/receive 可以看到前端展示的收货地址 ![BLOG_20190629_221038_11](/media/blog/images/2019/06/BLOG_20190629_221038_11.png "博客图集BLOG_20190629_221038_11.png") #### Vue中新增收货地址 ![BLOG_20190629_221032_86](/media/blog/images/2019/06/BLOG_20190629_221032_86.png "博客图集BLOG_20190629_221032_86.png") 添加完成之后,可以看到列表自动刷新了 ![BLOG_20190629_221027_39](/media/blog/images/2019/06/BLOG_20190629_221027_39.png "博客图集BLOG_20190629_221027_39.png") ```html <table width="100%" border="0" cellpadding="5" cellspacing="1" bgcolor="#dddddd"> <tbody> <tr> <td align="right" bgcolor="#ffffff">配送区域:</td> <td colspan="3" align="left" bgcolor="#ffffff"> <div class="addr"> <v-distpicker :province="newInfo.province" :city="newInfo.city" :area="newInfo.district" @province="getProvince" @city="getCity" @area="getArea"></v-distpicker> </div> </td> </tr> <tr> <td align="right" bgcolor="#ffffff">收货人姓名:</td> <td align="left" bgcolor="#ffffff"><input name="consignee" type="text" class="inputBg" id="consignee_0" value="ssss" v-model="newInfo.signer_name"> <span :class="{error:newInfo.signer_name==''}">(必填)</span></td> </tr> <tr> <td align="right" bgcolor="#ffffff">详细地址:</td> <td align="left" bgcolor="#ffffff"><input name="address" type="text" class="inputBg" id="address_0" v-model="newInfo.address"> <span :class="{error:newInfo.address==''}">(必填)</span></td> </tr> <tr> <td align="right" bgcolor="#ffffff">手机:</td> <td align="left" bgcolor="#ffffff"><input name="mobile" type="text" class="inputBg" id="mobile_0" v-model="newInfo.signer_mobile"><span :class="{error:newInfo.signer_mobile==''}">(必填)</span></td> </tr> <tr> <td align="right" bgcolor="#ffffff">&nbsp;</td> <td colspan="3" align="center" bgcolor="#ffffff"> <button class="bnt_blue_2" @click="addReceive">新增收货地址</button> </td> </tr> </tbody> </table> ``` 当用户点击 新增收货地址 ,会调用`addReceive()`函数 ```JavaScript addReceive() { //提交收获信息 addAddress(this.newInfo).then((response) => { alert('添加成功'); // 重置新的 this.getReceiveInfo(); this.newInfo = Object.assign({}, this.newInfoEmpty); }).catch(function (error) { console.log(error); }); }, ``` 然后请求`addAddress`api,请求成功后,请求`getReceiveInfo()`刷新收货地址列表,清空输入框 #### Vue中删除收货地址 当用户点击`<button class="bnt_blue_2" @click="deleteInfo(item.id)">删除</button>`删除时,调用`deleteInfo(id, index)`函数 ```JavaScript deleteInfo(id, index) { // 删除收获人信息 delAddress(id).then((response) => { alert('删除成功'); this.getReceiveInfo(); }).catch(function (error) { console.log(error); }); } ``` 之后调用`delAddress(id)`api进行地址删除,删除成功后弹框提示,并刷新收货地址列表。 #### Vue中修改收货地址 当用户点击`<button class="bnt_blue_2" @click="confirmUpdate(item.id, index)">确定修改</button>`会调用`confirmUpdate(id, index)`函数 ```JavaScript confirmUpdate(id, index) { // 更新收获信息 updateAddress(id, this.receiveInfoArr[index]).then((response) => { alert('修改成功'); this.getReceiveInfo(); }).catch(function (error) { console.log(error); }); }, ``` 之后调用`updateAddress(id, this.receiveInfoArr[index])`api进行地址更新,更新成功后弹框提示,并刷新收货地址列表。 ![BLOG_20190629_221015_26](/media/blog/images/2019/06/BLOG_20190629_221015_26.png "博客图集BLOG_20190629_221015_26.png")

很赞哦! (0)

文章交流

  • emoji
0人参与,0条评论

当前用户

未登录,点击   登录

站点信息

  • 建站时间:网站已运行590天
  • 系统信息:Linux
  • 后台程序:Python: 3.6.6
  • 网站框架:Django: 2.2.9
  • 文章统计:222 篇
  • 文章评论:40 条
  • 腾讯分析网站概况-腾讯分析
  • 百度统计网站概况-百度统计
  • 微信公众号:扫描二维码,关注我们
返回
顶部
标题 换行 登录
网站