设为首页 收藏本站
查看: 509|回复: 0

初始Django序列化组件Serializer

[复制链接]
累计签到:504 天
连续签到:1 天
发表于 2022-12-16 01:07:30 | 显示全部楼层 |阅读模式
# Serializer类,如何序列化
1、需要序列化什么,必须写一个类继承serializer.Serializer
2、像序列化什么字段,就在类里面写什么字段,一般情况下序列化的字段和models都是一样的,但是想写不一样的就可以通过source='字段名'来控制
[source3个作用(很多字段类)]
    修改字段名
    隐藏的book.方法,eg:source="publish.email" ==> book.publish.email
    执行类的方法 类的绑定方法
3、序列化queryset(列表也可以,因为queryset继承了列表)和真正的对象
    1、序列化得到一个字段,序列化对象.data
        book_ser=BookSerializer(对象)
        Response(book_ser.data)
    2、自己封装Response方法
        class MyResponse():
            def __init__(self):
                self.status=100
                self.msg='成功'
            @property
            def get_dict(self):
                return self.__dict__
        if __name__ == "__main__"
            res=MyResponse()
            res.data={'name':'lqz'} #对象给他的data属性加值,会自动保存到__init__里面去,在后面导入这个模块就可以了,然后需要该值就生成对象,res=MyResponse(),res.status=102就可以了
            res.get_dict
            print()
4、反序列化 view中的put方法 book_ser=BookSerializer(instance=要序列化的对象,data= request.data)
[5、字段验证顺序:]
    1、序列化类中,给字段加属性,
    2、局部和全局钩子函数,
    3、写一个函数,在Serializer字段中加入validators=[函数地址]
    4、调用is_valid()就会走验证,先走字段验证完,在走局部钩子,循环结束完,最后再走全局钩子,所以可以总结出来,在全局的Validate数据是符合上面的规则的数据
    5、*了解*:is_valid(),里面加入raise_exception=True只要验证不通过就直接抛异常,不会去捕获了
6、修改保存---》调用序列化对象.save(),但是要重写Serializer类的update方法,有一个一个字段去核对
    def update(self, instance, validated_data):
        # instance是book的这个对象
        # validated_data是校验后的数据
        instance.name=validated_data.get('name')
        instance.price=validated_data.get('price')
        instance.author=validated_data.get('author')
        instance.publish=validated_data.get('publish')
        instance.save() # instance这个是book对象=orm提供的save()
        return instance # 后续可能需要用到所以返回回去
    [*补充说明*]
        如果前端传过来的数据的字段不是在同一张表,那么我们需要通过instance.字段把对象取出来,然后进行orm的保存操作create

7、反序列化的新增
    1、和反序列化新增的差别就在与没有instance这个修改对象
    2、book_ser=BookSerializer(data= request.data),通过源码可以看到一定要写data=request.data要不然会把这个传给了instance了
    [3、源码可知,当序列化对象(book_ser).save()时候:
        [1、当同时在字段中有instancedata的时候会自动调用update方法,-
        [2、只有data的时候会调用create方法]
            重写create可以很复杂
            # ser.py 序列化类重写create方法
            def create(self, validated_data):# 传统意义需要一个一个关键字传入,但是现在**打散会更加合适
                instance = Book.objects.create(**validated_data)
                return instance
            *补充*
                [validated_data中如如果有一些数据是不必要的,可以通过.pop('key')删除]

8、ModelSerializer 跟模型做对应
        1、基本用法
            class BookModelSerializer(serializers.ModelSerializer):
                def validate_price(self, data):
                    pass
                publish=serializers.CharField(source='publish.name')
                [class Meta:
                    model=Book  # 对应上models.py中的模型]
                    fields='__all__' [序列化全部字段]
                    # fields=('name','price','id','author','publish') # 只序列化指定的字段
                    # exclude=('name',) #跟fields不能都写,写谁,就表示排除谁
                    # read_only_fields=('price',)
                    # write_only_fields=('id',) #弃用了,使用extra_kwargs
                    extra_kwargs = {  # 类似于这种形式name=serializers.CharField(max_length=16,min_length=4)
                        'price': {'write_only': True,max_length:16,min_length:4},
                    }
                [1、字段自己的校验]
                直接通过extra_kwargs传过去 :
                [类似于这种形式name=serializers.CharField(max_length=16,min_length=4)==>'price': {'write_only': True,max_length:16,min_length:4}]
                ,相当于在之前Serializer中字段里面写了各种条件   
                [2、在类中写钩子函数]
                    跟之前一模一样,在class这个类下面写局部钩子
                    def validate_price(self, data):  # validate_字段名  接收一个参数
                        # 如果价格小于10,就校验不通过
                        # print(type(data))
                        # print(data)
                        if float(data) > 10:
                            return data
                        else:
                            # 校验失败,抛异常
                            raise ValidationError('价格太低')
                        # 全局钩子
                    def validate(self, validate_data):  # 全局钩子
                        print(validate_data)
                        author = validate_data.get('author')
                        publish = validate_data.get('publish')
                        if author == publish:
                            raise ValidationError('作者名字跟出版社一样')
                        else:
                            return validate_data
                [3、如何通过对对象拿到对象的属性]
                fields=('name','price','id','author','publish')
                publish = serializer.Serializer(source="publish.name") 在ModelSerializer中自动会有class Meta:model=Book中的book对象,只是隐藏了
                这样就可以把publish覆盖了
                [4、自定义createupdate方法]
                def create():
                    pass
                def update():
                    pass
                自己写完会优先用自己的方法
13、many源码,many=True能够序列化多条数据的原因
[序列化多条,需要传many=True]
book_ser=BookModelSerializer(books,many=True)
book_one_ser=BookModelSerializer(book)
print(type(book_ser))
#<class 'rest_framework.serializers.ListSerializer'> 这里面列表中对应的都是modelSerializer的对象
print(type(book_one_ser))
#<class 'app01.ser.BookModelSerializer'>
[核心思想]
# 对象的生成--》先调用类的__new__方法,生成空对象
# 对象=类名(name=lqz),触发类的__init__()
def __new__(cls, *args, **kwargs):
    if kwargs.pop('many', False):
        return cls.many_init(*args, **kwargs)
    # 没有传many=True,走下面,正常的对象实例化
    return super().__new__(cls, *args, **kwargs)
[补充魔法方法]
# 类的__new__方法控制对象的生成
# __str__ 当对象被打印的时候触发这个方法、
# __dict__ 类来调用会把类的属性组合成字典,对象.__dict__会把对象的属性组成字典
# __call__ 对象被调用会触发
# __getattr__ 独享点属性时候会被触发这个方法

14、接口:统一子类的行为(其他语言)
        python中推崇鸭子类型,子类写了该方法,就不用父类的了,但是接口的概念也是很有必要的统一规范如何实现:
            1、abc模块控制
            2、raise抛异常控制

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-1003380-1-1.html 上篇帖子: Django值drf序列化与反序列化浅层刨析 下篇帖子: Django-drf中详解Request对象和Response对象、初始GenericAPIView
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表