第七天

作者: tomtiddler | 来源:发表于2018-09-07 01:50 被阅读0次

    个人中心续

    用户留言功能

    以下代码两个问题:

    1. 为什么序列化的id创建时不需要输入而读取时能直接输出
    2. add_time 的read_only,和格式化
    class LeavingMsgSerializer(serializers.ModelSerializer):
        user = serializers.HiddenField(
            default=serializers.CurrentUserDefault()
        )
        add_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M:%S")
    
        class Meta:
            model = UserLeavingMessage
            fields = ("id", "user", "msg_type", "subject", "message", "file", "add_time")
    

    注释掉此行又没有出错了,不知道为什么,下次记录下错误栈
    个人觉得好的习惯还是采用下面这行代码,然后get_queryset直接调用该属性,这样代码会更有结构
    queryset = UserFav.objects.all() # 之前可能由于某些第三方包的依赖问题此行需要保留

    收货地址功能

    用戶收货地址功能。
    1.model中更改字段以适应前端;
    2.验证手机号码的validate;隐藏user使无法指定user值;
    3.view中指定用户权限=>对应主要是非安全方法->应该不包括创建方法;
    4.创建在serializer中指定当前用户;
    5.get方法在get_queryset中指定用户。
    ----------------------写得真乱

    购物车

    加入购物车

    此处不使用modelserializer,因为该类会验证unique_together字段,然而更新时该字段是存在的,验证会报错。暂时没理解。最好看一遍源码。

    *******************************model中*******************************
            unique_together = ("user", "goods")
    *******************************serializer中*******************************
    class ShopCartSerializer(serializers.Serializer):
        user = serializers.HiddenField(
            default=serializers.CurrentUserDefault()
        )
        nums = serializers.IntegerField(required=True, min_value=1, label="数量",
                                        error_messages={
                                            "min_value": "商品数量不能小于1",
                                            "required": "请填写购买数量",
                                        })
        goods = serializers.PrimaryKeyRelatedField(queryset=Goods.objects.all(), required=True, label="商品")
    
        def create(self, validated_data):
            user = self.context["request"].user
            nums = validated_data["nums"]
            goods = validated_data["goods"]
    
            existed = ShoppingCart.objects.filter(user=user, goods=goods)
    
            if existed:
                existed = existed[0]
                existed.nums += nums
                existed.save()
            else:
                existed = ShoppingCart.objects.create(**validated_data)
    
            return existed
    
    

    修改商品数量

     def update(self, instance, validated_data):
            # 修改商品数量
            # 为什么此处直接是实例,猜测和retrieve方法相关。
            instance.nums = validated_data["nums"]
            instance.save()
            return instance
    
    

    以下两句代码分别提供了read和list功能,更具体的细节需要查看源码,此处只是提供了一个相当于配置的功能

    lookup_field = "goods_id"  # retrieve方法
    
        def get_queryset(self):  # list方法
            return ShoppingCart.objects.filter(user=self.request.user)
    

    vue联调

    detailserializer中外键goods实例化goods = GoodsSerializer(many=False)
    动态加载serializer

      def get_serializer_class(self):
            if self.action == "list":
                return ShopCartDetailSerializer
            else:
                return ShopCartSerializer
    

    前端header组件删除商品需要手动更新,结生成订单页面手动输入数量需要点击+或者-号才能真正完成更新。

    订单

    订单列表和订单删除

    serializer

    class OrderSerializer(serializers.ModelSerializer):
        # 个人猜测此属性只是隐藏,并设置默认值,并不能防止权限,权限由其他设置搞定
        user = serializers.HiddenField(
            default=serializers.CurrentUserDefault()
        )
        pay_status = serializers.CharField(read_only=True)
        trade_no = serializers.CharField(read_only=True)
        order_sn = serializers.CharField(read_only=True)
        pay_time = serializers.DateTimeField(read_only=True)
    
        def generate_order_sn(self):
            # 当前时间+user_id+随机数
            random_ins = Random()
            order_sn = "{time_str}{user_id}{ran_str}".format(time_str=time.strftime("%Y%m%d%H%M%S"),
                                                             user_id=self.context["request"].user.id,
                                                             ran_str=random_ins.randint(10, 99))
            return order_sn
    
        def validate(self, attrs):
            attrs["order_sn"] = self.generate_order_sn()
            return attrs
    
        class Meta:
            model = OrderInfo
            fields = "__all__"
    

    viewset

    class OrderViewset(mixins.ListModelMixin,
                       mixins.CreateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.RetrieveModelMixin,
                       viewsets.GenericViewSet):  # 订单不允许修改,所以不继承modelviewset
        """
        订单管理
        list:
            获取个人订单
        delete:
            删除订单
        create:
            新增订单
        """
        authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)  # 对象级别认证
        permission_classes = (permissions.IsAuthenticated, IsOwnerOrReadOnly)  # 验证是否为登录用户,拥有的用户。
        serializer_class = OrderSerializer
    
        def get_queryset(self):  # list方法
            return OrderInfo.objects.filter(user=self.request.user
    
        def perform_create(self, serializer):  # 生成订单,增加订单商品,清空购物车,
            order = serializer.save()
            shop_carts = ShoppingCart.objects.filter(user=self.request.user)
            for shop_cart in shop_carts:
                order_goods = OrderGoods()
                order_goods.goods = shop_cart.goods
                order_goods.goods_num = shop_cart.nums
                order_goods.order = order
                order_goods.save()
    
                shop_cart.delete()
            return order
    

    订单详情完成

    动态加载serializer。serializer类内嵌serializer类。relate_name跟前台有很大关系,同时和serializer的嵌套也有很大关系。
    related_name很重要的一个属性

    class OrderGoods(models.Model):
    
        # 此处related_name用于serializer实例化嵌套serializer,从而和前端适配,所以此处需要和前端适配。
        order = models.ForeignKey(..., related_name="goods", verbose_name='订单信息')
    

    serializer

    class OrderGoodsSerializer(serializers.ModelSerializer):
        goods = GoodsSerializer(many=False)
    
        class Meta:
            model = OrderGoods
            fields = "__all__"
    
    class OrderDetailSerializer(serializers.ModelSerializer):
        goods = OrderGoodsSerializer(many=True)
    
        class Meta:
            model = OrderInfo
            fields = "__all__"
    
    

    viewset中动态加载

        def get_serializer_class(self):
            if self.action == "retrieve":
                return OrderDetailSerializer
            else:
                return OrderSerializer
    

    相关文章

      网友评论

          本文标题:第七天

          本文链接:https://www.haomeiwen.com/subject/vjxxgftx.html