序列化器中通过context属性获得request和view视图对象与self.initial_date

序列化器中通过context属性获得request和view视图对象与self.initial_date

序列化器中的属性,可以通过self.context获得一个字典。里面储存request,view,format

也可以在序列化对象中指定context中传入的数据

request:请求对象

view:视图对象,可以通过self.view.kwargs[‘url中关键字参数’]------如:

url: sms_codes/(?P<mobile>1[3-9]\d{9}) (通过手机号获取短信验证码),
类视图:SmsCode(View) (类视图对象:smscode = SmsCode() )
获取:mobile = smscode.kwargs[“mobile”]
serializer = AccountSerializer(account, context={'request': request})

通过context参数附加的数据,可以通过Serializer对象的context属性获取。

序列化器中返回的数据是以模型类中的字段为key,数据为vilue。如果需要返回的不是序列化器中的内容,可以重构data方法。

  • # serializer是序列化器对象,
    serializer.data  # 储存的是需要返回的数据
    

initial_data是BaseSerializer里初始化的属性,是__储存前端传入的数据__。而DRF底层的验证方法只能验证字典,如果是其他数据则返回的是空的数据。

  • def validate(self, attrs):
        #     # initial_data是BaseSerializer里初始化的属性,是储存前端传入的数据。而DRF底层的验证方法只能验证字典,如果是其他数据则返回的是空的数据。
        #     print(self.initial_data)
        #     return self.initial_data
    
    

解决方法:

通过self.context[request].data直接获得前端传入的数据,然后重构

在验证方法中__(validate)__通过,self.initial_date也可以获得前端传入的数据,直接返回也可

  • class SKUSerializer(serializers.ModelSerializer):
        '''
            返回关联spu表的名称和关联的分类表的名称
        '''
    
        spu = serializers.StringRelatedField(read_only=True)
        category = serializers.StringRelatedField(read_only=True)
    
        # 返回模型类里的spu_id和category_id
        spu_id = serializers.IntegerField()
        category_id = serializers.IntegerField()
    
        # 返回商品的规格信息,在商品规格详情表(SKUSpecification)中有个外键sku关联了当前的SKU表
        specs = SKUSpecificationSerializer(many=True)
    
        class Meta:
            model=SKU
            fields='__all__'
    
    
    
        # 解决specs传入的值是空的问题
        # 方法一:
        # def validate(self, attrs):
        #     # initial_data是BaseSerializer里初始化的属性,是储存前端传入的数据。而DRF底层的验证方法只能验证字典,如果是其他数据则返回的是空的数据。
        #     print(self.initial_data)
        #     return self.initial_data
    
    
    
        def create(self, validated_data):    # create方法是不支持可以写的嵌套字段的(StringRelatedField,PrimaryKeyRelatedField,或序列化器嵌套),因此要想保存,需要重写create
            # 因为sku表中没有specs字段,但是保存的时候需要保存商品规格信息,所以需要重写create方法
    
            # 解决specs传入的值是空的问题
            # 方法一:
            # specs=validated_data['specs']
    
            # 解决specs传入的值是空的问题
            # 方法二:
            specs = self.context['request'].data.get('specs')
    
            # 因为specs是外键关联字段,外键关联字段为只读,如果不写read_only=True会报错,但是我们需要储存specs。所以将validated_data中的specs字段,先删除掉
            del validated_data['specs']
    
            # 1. 保存sku表
            sku = SKU.objects.create(**validated_data)
    
            # 2. 保存sku规格选项表
            # 因为specs是一个列表,所以需要遍历
            for spec in specs:        	    												SKUSpecification.objects.create(sku=sku,spec_id=spec['spec_id'],option_id=spec['option_id'])
    
            return sku
    
    
        def update(self, instance, validated_data):    # create方法是不支持可以写的嵌套字段的(StringRelatedField,PrimaryKeyRelatedField,或序列化器嵌套),因此要想保存,需要重写create
            # 因为sku表中没有specs字段,但是保存的时候需要保存商品规格信息,所以需要重写create方法
    
            # 解决specs传入的值是空的问题
            # 方法一:
            # specs=validated_data['specs']
    
            # 解决specs传入的值是空的问题
            # 方法二:
            # 通过context获得request属性
            specs = self.context['request'].data.get('specs')
            # 通过context获得view属性(视图对象)中的kwargs方法,获得前端了传的url参数
            pk = self.context['view'].kwargs['pk']
    
            # 因为specs是外键关联字段,外键关联字段为只读,如果不写read_only=True会报错,但是我们需要储存specs。所以将validated_data中的specs字段,先删除掉
            del validated_data['specs']
    
            # 1. 更改sku表
            instance.name=validated_data['name']
            instance.save()
    
            # 2. 更改sku规格选项表
            
            # 因为会有很多规格,所以用updata方法就不能实现了,先将原本的数据删除掉,然后重新创建
            SKUSpecification.objects.filter(sku=instance).delete()
            # 因为specs是一个列表,所以需要遍历
            for spec in specs:
                SKUSpecification.objects.create(sku=instance,spec_id=spec['spec_id'],option_id=spec['option_id'])
    
    
            return instance
    
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值