Serializers进阶之自由自在的序列化

话不多说,代码直接来:
首先设一个购物车的model:

# models.py
class ShoppingCart(models.Model):
    """
    购物车
    """
    user = models.ForeignKey(User, verbose_name=u"用户", on_delete=models.CASCADE)
    goods = models.ForeignKey(Goods, verbose_name=u"商品", on_delete=models.CASCADE)
    nums = models.IntegerField(default=0, verbose_name="购买数量")

    add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")

    class Meta:
        verbose_name = '购物车'
        verbose_name_plural = verbose_name
        unique_together = ("user", "goods")

    def __str__(self):
        return "%s(%d)".format(self.goods.name, self.nums)

这个表主要用来记录每个用户的购物车中的商品的数量

再来看看序列化

需求分析:
用户可以增/删/改/查,自己的购物车里的每个实例,且查整个购物车列表的时候,需要加载每个商品的一些详细信息,如图片,描述等,而删/改/增是不需要商品的详细信息的

那么根据需求,我们就可以给这个model做2个Serializer类,一个给list使用,一个给其他api使用

# serializers.py
class ShopCartDetailSerializer(serializers.ModelSerializer):
    goods = GoodsSerializer(many=False,)    # goods由原本的id变成具体的信息序列化
    class Meta:
        model = ShoppingCart
        fields = '__all__'

class ShopCartSerializer(serializers.Serializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )              # 默认采用请求者的身份,如此前端可以少post一个数据
    nums = serializers.IntegerField(required=True, min_value=1, error_messages={'min_value': '商品数量不能小于1',
                                                                                'required':'请选择购买数量'})
    goods = serializers.PrimaryKeyRelatedField(required=True,queryset=Goods.objects.all())

    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):
        # 修改商品数量
        instance.nums = validated_data['nums']
        instance.save()
        return instance

如此,视图中应该具有根据请求来改变Serializer的机制,

class ShoppingCartViewSet(viewsets.ModelViewSet):
    """
    购物车功能
    list:
    获取购物车详情
    create:
    加入购物车
    delete:
    删除购物车记录
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)  # 用户需登录,所有者
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    lookup_field = 'goods_id'

    def get_queryset(self):
        return ShoppingCart.objects.filter(user=self.request.user)

    def get_serializer_class(self):
        # 使用self.action来知道当前请求的动作有list,create,retrieve,delete等
        if self.action == 'list':
            return ShopCartDetailSerializer
        else:
            return ShopCartSerializer

你可能感兴趣的:(Django学习)