序列化器中通过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