第七天

2018-09-07  本文已影响0人  tomtiddler

个人中心续

用户留言功能

以下代码两个问题:

  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
上一篇 下一篇

猜你喜欢

热点阅读