收货地址管理

首先就是新增地址

看图分析所需要保存的字段

因为是用户的地址,所以在users应用中的models创建模型类

class Address(BaseModel):
"""
用户地址
"""
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='addresses', verbose_name='用户')
title = models.CharField(max_length=20, verbose_name='地址名称')
receiver = models.CharField(max_length=20, verbose_name='收货人')
province = models.ForeignKey('areas.Area', on_delete=models.PROTECT, related_name='province_addresses', verbose_name='省')
city = models.ForeignKey('areas.Area', on_delete=models.PROTECT, related_name='city_addresses', verbose_name='市')
district = models.ForeignKey('areas.Area', on_delete=models.PROTECT, related_name='district_addresses', verbose_name='区')
place = models.CharField(max_length=50, verbose_name='地址')
mobile = models.CharField(max_length=11, verbose_name='手机')
tel = models.CharField(max_length=20, null=True, blank=True, default='', verbose_name='固定电话')
email = models.CharField(max_length=30, null=True, blank=True, default='', verbose_name='电子邮箱')
is_deleted = models.BooleanField(default=False, verbose_name='逻辑删除') class Meta:
db_table = 'tb_address'
verbose_name = '用户地址'
verbose_name_plural = verbose_name
ordering = ['-update_time']

说明:

  • Address模型类中的外键指向Areas/models里面的Area,指明外键ForeignKey时,可以使用字符串应用名.模型类名来定义

  • related_name 在进行反向关联查询时使用的属性,如 city = models.ForeignKey('areas.Area', related_name='city_addresses')表示可以通过Area对象.city_addresses属性获取所有相关的city数据。

  • ordering 表名在进行Address查询时,默认使用的排序方式

然后就是怎么设置用户的默认收货地址

可以有两种方法,一是在收货地址这个模型类中多加一个字段,证明是默认收货地址,但是这个方法在设置默认地址和取消默认地址的时候,会很麻烦,取消默认地址的时候,需要先查哪个是默认地址,然后取消那个标记,然后再设置另外一个标记,这样多增加了数据库的操作。

第二种方法是在用户表中多加一个字段,外键关联到要设置默认地址的那条记录上,这里采用这种方法

为User模型类添加默认地址

class User(AbstractUser):
...
default_address = models.ForeignKey('Address', related_name='users', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='默认地址')
...

设置好之后执行数据库迁移

然后观察需要哪些接口

使用视图集

在users/view.py中增加代码

class AddressViewSet(CreateModelMixin, UpdateModelMixin, GenericViewSet):
"""
用户地址新增与修改
"""
serializer_class = serializers.UserAddressSerializer
permission_classes = [IsAuthenticated] def get_queryset(self):
return self.request.user.addresses.filter(is_deleted=False) def create(self, request, *args, **kwargs):
"""
保存用户地址数据
:param request:
:param args:
:param kwargs:
:return:
"""
# 检查用户地址数据的数量不能超过上限
# 获取用户地址的数量
count = request.user.addresses.count()
if count >= constants.USER_ADDRESS_COUNTS_LIMIT:
return Response({'message': '保存地址数据已达到上限'}, status=status.HTTP_400_BAD_REQUEST) return super().create(request, *args, **kwargs) def list(self, request, *args, **kwargs):
"""
用户地址列表数据
:param request:
:param args:
:param kwargs:
:return:
"""
queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True)
user = self.request.user
return Response({
'user_id': user.id,
'default_address_id': user.default_address_id,
'limit': constants.USER_ADDRESS_COUNTS_LIMIT,
'addresses':serializer.data,
}) def destroy(self, request, *args, **kwargs):
"""
处理删除的逻辑
:param request:
:param args:
:param kwargs:
:return:
"""
address = self.get_object()
address.is_deleted = True
address.save()
return Response(status=status.HTTP_204_NO_CONTENT) @action(methods=['put'], detail=True)
def status(self, request, pk=None):
"""
设置默认地址
:param request:
:param pk:
:return:
"""
address = self.get_object()
request.user.default_address = address
request.user.save()
return Response({'message': 'OK'}, status=status.HTTP_200_OK) @action(methods=['put'], detail=True)
def title(self, request, pk=None, address_id=None):
"""
修改标题
:param request:
:param pk:
:param address_id:
:return:
"""
address = self.get_object()
serializer = serializers.AddressTitleSerializer(instance=address, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)

路由设置

然后测试,成功

Django商城项目笔记No.17用户部分-用户中心用户地址管理的更多相关文章

  1. Django商城项目笔记No.12用户部分-QQ登录2获取QQ用户openid

    Django商城项目笔记No.12用户部分-QQ登录2获取QQ用户openid 上一步获取QQ登录网址之后,测试登录之后本该跳转到这个界面 但是报错了: 新建oauth_callback.html & ...

  2. Django商城项目笔记No.11用户部分-QQ登录1获取QQ登录网址

    Django商城项目笔记No.11用户部分-QQ登录 QQ登录,亦即我们所说的第三方登录,是指用户可以不在本项目中输入密码,而直接通过第三方的验证,成功登录本项目. 若想实现QQ登录,需要成为QQ互联 ...

  3. Django商城项目笔记No.10用户部分-登录接口

    Django商城项目笔记No.10用户部分-登录接口 添加url路由 接下来第二步,增加返回内容: 增加结果如下: 配置:上边的方法定义了返回的内容都有哪些,那这个方法jwt还不知道,需要配置: 修改 ...

  4. Django商城项目笔记No.9用户部分-注册接口签发JWTtoken

    Django商城项目笔记No.9用户部分-注册接口签发JWTtoken 我们在验证完用户的身份后(检验用户名和密码),需要向用户签发JWT,在需要用到用户身份信息的时候,还需核验用户的JWT. 关于签 ...

  5. Django商城项目笔记No.8用户部分-注册接口实现

    Django商城项目笔记No.8用户部分-注册接口实现 users的view.py中增加如下代码 class RegisterUserView(CreateAPIView): "" ...

  6. Django商城项目笔记No.7用户部分-注册接口-判断用户名和手机号是否存在

    Django商城项目笔记No.7用户部分-注册接口-判断用户名和手机号是否存在 判断用户名是否存在 后端视图代码实现,在users/view.py里编写如下代码 class UsernameCount ...

  7. Django商城项目笔记No.6用户部分-注册接口-短信验证码实现celery异步

    Django商城项目笔记No.4用户部分-注册接口-短信验证码实现celery异步 接上一篇,如何解决前后端请求跨域问题? 首先想一下,为什么图片验证码请求的也是后端的api.meiduo.site: ...

  8. Django商城项目笔记No.5用户部分-注册接口-短信验证码

    Django商城项目笔记No.4用户部分-注册接口-短信验证码 短信验证码也保存在redis里(sms_code_15101234567) 在views中新增SMSCodeView类视图,并且写出步骤 ...

  9. Django商城项目笔记No.4用户部分-注册接口-图片验证码

    Django商城项目笔记No.4用户部分-注册接口-图片验证码 1.首先分析注册业务接口 1.1.分析可得,至少这么几个接口 图片验证码 短信验证码 用户名是否存在 手机号是否存在 整体注册接口 图片 ...

随机推荐

  1. 并发编程之 Java 三把锁

    前言 今天我们继续学习并发.在之前我们学习了 JMM 的知识,知道了在并发编程中,为了保证线程的安全性,需要保证线程的原子性,可见性,有序性.其中,synchronized 高频出现,因为他既保证了原 ...

  2. 在ASP.NET MVC中使用Grid.mvc

    很久没有写ASP.NET的博文了,专心工作嘛,今天写一点MVC的博文,也是自己练习来的,是使用grid.mvc来显示数据. 首先打开Manage Nuget Packages,搜索grid.mvc并安 ...

  3. 反射实现Model修改前后的内容对比

    在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责. 首先我们要创建一个User类 public class User { priv ...

  4. More Effective C++ 35 条款

    一.基础议题(basics) 条款1:仔细区别 pointers 和 references(Distinguish between pointers and references) 一个基本的语法问题 ...

  5. 选择ORACLE数据库字符集

    如何选择数据库的字符集是一个有争议的话题,字符集本身涉及的范围很广,它与应用程序.客户的本地环境.操作系统.服务器等关系很密切,因此要做出合适的 选择,需要明白这些因素之间的关系.另外对字符集的基本概 ...

  6. asp.net错误记录

    //登录 jquery-ajax post请求后台无法获取数据,get就可以!!!原因:get方法,后台接收用Request.QueryString["para1"];post方法 ...

  7. 撩课-Web大前端每天5道面试题-Day27

    1.浏览器缓存? 浏览器缓存分为强缓存和协商缓存.当客户端请求某个资源时,获取缓存的流程如下: 先根据这个资源的一些 http header 判断它是否命中强缓存, 如果命中,则直接从本地获取缓存资源 ...

  8. MyBatis动态添加—trim标签

    做添加时,部分字段有值,没值的字段不添加,这就是动态添加,使用 trim 标签就可以实现. <insert id="insertSysUser" parameterType= ...

  9. centos7下没有iptables

    从centos7开始使用linux,之前版本的没有深入了解过,今天要开放个端口,需要有防火墙的相关操作,从网上查资料都是编辑/etc/sysconfig目录下面的iptables文件,可我进入这个文件 ...

  10. Netty中的LoggingHandler()

    当添加.addLast("logging", new LoggingHandler(LogLevel.INFO))这行代码时 Netty就会以给定的日志级别打印出LoggingHa ...