WED.序列化类之 Serializer

WED.序列化类之 Serializer

类中方法和函数的区别

方法

绑定给对象的方法
  • 内有任何装饰器

  • 对象来调用,会自动传值,把对象当做第一个参数传进来

绑定给类的方法
  • 类来调用,会自动传值,把类当做第一个参数传进来

函数

  • 通过 @staticmethod 修饰的函数被称为普通函数,也被称为静态方法,有几个值,调用时就传入几个值。
注意
1、对象可以调用类的方法,且仍然会把类作为第一个参数自动传入

2、类也可以调用对象的方法,'但只作为普通函数',不会将对象或类作为第一个参数自动传入

3、方法会自动传参,而函数有几个值就传几个值

4、方法不一定是方法,得看是谁来调用

DRF 中 APIView 的执行流程

1、APIView 中的 as_view 代码
		view = super().as_view(**initkwargs)
    return csrf_exempt(view)
  
2、view 内部本质执行了 self.dispatch()
    - 执行了 APIView 的 dispatch
    		-- request = self.initialize_request(request, *args, **kwargs)
    		--self.initial(request, *args, **kwargs)
      
3、处理了异常(包含三大认证和视图类中的方法)

DRF的Request类的对象

只要继承了 APIView,后续的视图类中使用的 request 对象,都是 DRF 的 Request 类的对象
    1、但是用起来,跟之前 Django 的一样
    2、request.data, post 和 put 提交的数据,都会在里面,字典形式
    		- urlencoded编码 --> request.data 是 QueryDict 的对象
        - formdata编码 --> request.data 是 QueryDict 的对象
        - json编码 --> request.data 是 dict
				- request.query_params --> 它就是原来的request.GET, 即 self._request.GET

鸭子类型

  • Python 中不需要父类或接口来约束子类,而子类中有这个方法即称为鸭子类型

  • Python 推崇人为约束,即程序员自行约束

  • 但鸭子类型存在风险,若不通过约束,则可能存在方法不同名无法调用的情况

序列化类之Serializer

序列化类常用字段

# 重点的:
'''
    CharField
    IntegerField
    DecimalField
    DateTimeField
    DateField

    ListField
    DictField
    '''

# 其他还有很多但的忽略

序列化类常用字段参数

# 通用的
read_only	表明该字段仅用于序列化输出,默认 False(重点)
write_only	表明该字段仅用于反序列化输入,默认 False(重点)
required	表明该字段在反序列化时必须输入,默认 True(了解)
default	    反序列化时使用的默认值(了解)
allow_null	表明该字段是否允许传入 None,默认 False(了解)
validators	该字段使用的验证器(写函数的列表,使用这些函数校验该字段)(了解)
error_messages	包含错误编号与错误信息的字典


# 其他的
# CharField
max_length	最大长度
min_lenght	最小长度
allow_blank	是否允许为空
trim_whitespace	是否截断空白字符

# IntegerField
max_value	最小值
min_value	最大值

反序列化(重写 Create 和 Update)

# 重点:
	-如果想序列化和反序列化都用一个序列化类,可以使用如下俩字段控制
	-read_only	表明该字段仅用于序列化输出,默认 False(重点)
	-write_only	表明该字段仅用于反序列化输入,默认 False(重点)
    -如果写起来比较麻烦,可以使用两个序列化类,一个序列化,一个反序列化
# source 的用法
	name1 = serializers.CharField(source='name')--->意思是name1映射成models中的name
    
    
# 如果继承 Serializer 类,要修改和保存,一定要重写 update 和 create
	BookSerializer---》Serializer---》BaseSerializer--save的核心代码
         if self.instance is not None:
            self.instance = self.update(self.instance, validated_data)
        else:
            self.instance = self.create(validated_data)

SerializerMethodField 的使用

class BookSerializer(serializers.Serializer):
    price = serializers.IntegerField()

    name = serializers.CharField()
    # publish = serializers.CharField()

    # 显示出版社的详情

    ## 方式一(在序列化类中写)
    publish_name = serializers.SerializerMethodField(read_only=True)  # 只能用来做序列化
    def get_publish_name(self,obj):
        # obj 就是当前要序列化的book对象
        return obj.publish.name
        return {'name':obj.publish.name,'addr':obj.publish.addr}

    # 方式二(在模型类中写方法,方法返回什么,这个字段就是什么)(在表模型中写用的多)
    publish_detail=serializers.CharField()
    publish_detail=serializers.DictField()


    ## 方式三
    publish_detail = serializers.CharField(source='publish.addr')

序列化类之 ModelSerializer

from .models import Book, Publish


class PublishModelSerializer(serializers.ModelSerializer):
#     # 指定跟表的对应关系
    class Meta:
        model = Publish  # 跟哪个表有关系
        # fields =['name','addr']
        # fields ='__all__'  # 所有字段,只序列化字段,不序列化方法
        fields = ['name', 'addr', 'name_detail']
        # 给字段类,传递参数、属性
        extra_kwargs={
            'addr':{'max_length':8,'min_length':3,'write_only':True},
            'name':{'write_only':True}
#         }
#         # 不重要的
        exclude=['name']  '它跟 fields 只能有一个'
        # depth=1  返回其下所属全部字段,不能只返回其中个别字段


    #1 不用重写 create 和 update

    #2  在出版社名字后加 _vip
    # 方式一
    # name=serializers.SerializerMethodField()
    # def get_name(self,obj):
    #     return obj.name+'_vip'

    # 方式二,在表模型中定义一个name_detail,在fields中写一些字段或方法

    # 序列化的时候使用 name_detail,反序列化的时候使用 name
    # name_detail = serializers.CharField(read_only=True)  如果是个方法,这句可以不写
    # name = serializers.CharField(write_only=True)

    #3  限制addr,最大长度8,最小长度3

序列化类全局,局部钩子

# 局部钩子:给某个字段再增加校验(固定用法),定义一个方法,名字为 validate_ 字段名
def validate_addr(self, item):
    if item.startswith('sb'):
    # 抛异常,不能以 sb 开头
        raise ValidationError('不能以 sb 开头')
    else:
        return item

# 全局钩子
# 限制出版社的名字不能等于出版社地址
def validate(self, attrs):
  	name = attrs.get('name')
  	addr = attrs.get('addr')
    if name == addr:
        raise ValidationError('name 和 addr 不能一样')
    else:
        return attrs
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值