zoukankan      html  css  js  c++  java
  • Django商城项目笔记No.17用户部分-用户中心用户地址管理

    收货地址管理

    首先就是新增地址

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

    因为是用户的地址,所以在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']
    View Code

    说明:

    • 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)
    View Code

    路由设置

    然后测试,成功

  • 相关阅读:
    MYsql增删改查
    粘包问题
    模拟ssh远程执行命令
    Socket抽象层
    基于TCP协议的socket套接字编程
    TCP协议的三次握手和四次挥手
    大话OSI七层协议
    网络架构及其演变过程
    互联网和互联网的组成
    Windows安装MySQL
  • 原文地址:https://www.cnblogs.com/blog-rui/p/9943894.html
Copyright © 2011-2022 走看看