三流

import sys
#标准输出流
sys.stdout.write('123\n')
sys.stdout.write('456\n')
#标准输入流
res=sys.stdin.readline()
print(res)
#标准错误流:将括号内数据作为错误输出
sys.srderr.write('abc\n')
sys.stderr.write('xyz\n)

注意:每个流之间为异步提交,流内为同步提交.

JSON文件格式

JSON 值可以是:
  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组(在方括号中)
  • 对象(在花括号中)
  • null
JSON 语法规则:
  • 数据在名称/值对中
  • 数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组

为什么要使用序列化器

drf中的response方法只能接收json数格式,并将json数据解析为二进制格式发送给前端,也可以更以更方便的方法对数据进行验证以及数据库操作.

序列化家族

  1. Serializer类,底层是序列化类,(了解原理)
  2. ModelSerializer类,模型序列化类(核心)
  3. ListSerializer类:群操作序列化类(辅助类)

手动序列化

前后端交互,通过json格式文件进行传输,使用djangoORM语句将对象从数据库中找出来进行交互,需要手动序列化转为json格式再进行交互.

class UserV1APIView(APIView):
# 单查群查
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
user_dic = models.User.objects.filter(is_delete=False, pk=pk).values('username', 'sex', 'img').first()
if not user_dic:
return Response({
'status': 1,
'msg': 'pk error',
}, status=400) user_dic['img'] = '%s%s%s' % (settings.BASE_URL, settings.MEDIA_URL, user_dic.get('img'))
return Response({
'status': 0,
'msg': 'ok',
'results': user_dic
})
else:
user_query = models.User.objects.filter(is_delete=False).values('username', 'sex', 'img').all()
for user_dic in user_query:
user_dic['img'] = '%s%s%s' % (settings.BASE_URL, settings.MEDIA_URL, user_dic.get('img'))
user_list = list(user_query)
return Response({
'status': 0,
'msg': 'ok',
'results': user_list
})

Serializer序列化类

序列化

新建serializers.py文件,文件中进行Serializer类的操作

from rest_framework import serializers
from django.conf import settings
from . import models
class UserSerializer(serializers.Serializer):
# 1)字段名与字段类型要与处理的model类对应
# 2)不提供的字段,就不参与序列化给前台
# 3)可以自定义序列化字段,采用方法序列化,方法固定两个参数,第二个参数就是参与序列化的model对象
# (严重不建议自定义字段名与数据库字段名重名,由get_自定义字段名方法的返回值提供字段值)
username = serializers.CharField()
# sex = serializers.IntegerField()
# sex = serializers.SerializerMethodField() # 不建议这样命名
gender = serializers.SerializerMethodField() def get_gender(self, obj):
return obj.get_sex_display() # 注:在高级序列化与高级视图类中,drf默认帮我们处理图片等子资源
icon = serializers.SerializerMethodField() def get_icon(self, obj):
return '%s%s%s' % (settings.BASE_URL, settings.MEDIA_URL, obj.img)

使用改名显示字段,官方建议使用在models类中定义属性方法

#models中
# 第二种自定义序列化字段(插拔式,提倡使用)
@property
def gender(self):
return self.get_sex_display() @property
def icon(self):
from django.conf import settings
return '%s%s%s' % (settings.BASE_URL, settings.MEDIA_URL, self.img)

总结:

  1. 设置序列化字段,字段名与字段类型要与处理的model类属性名对应(只参与序列化的类型不需要设置条件)

  2. model类中有的字段,但在序列化中没有对应字段,该类字段不参与序列化

  3. 自定义序列化字段(方法一),字段类型为SerializerMethodField(),值有 get_自定义字段名(self, model_obj) 方法提供,

    一般值都与参与序列化的model对象(model_obj)有关

反序列化

class UserDeSerializer(serializers.Serializer):
# 系统校验字段
username = serializers.CharField(min_length=3, max_length=16, error_messages={
'min_length': '太短',
'max_length': '太长'
})
password = serializers.CharField(min_length=3, max_length=16) # 不写,不参与反序列化,写就必须参与反序列化(但可以设置required=False取消必须)
# required=False的字段,前台不提供,走默认值,提供就一定进行校验;不写前台提不提供都采用默认值
sex = serializers.BooleanField(required=False) # 自定义校验字段:从设置语法与系统字段没有区别,但是这些字段不能参与入库操作,需要在全局钩子中,将其取出
re_password = serializers.CharField(min_length=3, max_length=16) # 局部钩子:
# 方法就是 validate_校验的字段名(self, 校验的字段数据)
# 校验规则:成功直接返回value,失败抛出校验失败信息
def validate_username(self, value):
if 'g' in value.lower():
raise serializers.ValidationError('名字中不能有g')
return value # 全局钩子:
# 方法就是 validate(self, 所有的校验数据)
# 校验规则:成功直接返回attrs,失败抛出校验失败信息
def validate(self, attrs):
password = attrs.get('password')
re_password = attrs.pop('re_password')
if password != re_password:
raise serializers.ValidationError({'re_password': '两次密码不一致'})
return attrs # 在视图类中调用序列化类的save方法完成入库,Serializer类能做的增入库走create方法,改入库走update方法
# 但Serializer没有提供两个方法的实现体
def create(self, validated_data):
return models.User.objects.create(**validated_data) # instance要被修改的对象,validated_data代表校验后用来改instance的数据
def update(self, instance: models.User, validated_data):
# 用户名不能被修改
validated_data.pop('username')
models.User.objects.filter(pk=instance.id).update(**validated_data)
return instance

对于数据的校验,需要通过自定义系统方法,自定义局部以及全局钩子的方法进行校验.还需要自己写create以及update方法.

ModelSerializer序列化类

class UserModelSerializer(serializers.ModelSerializer):
# 第一种自定义序列化字段:该字段必须在fields中设置
# gender = serializers.SerializerMethodField()
# def get_gender(self, obj):
# return obj.get_sex_display() # 自定义反序列化字段同Serializer类,且规则只能在此声明中设置,或是在钩子中设置,
# 在extra_kwargs中对其设置的无效
# 注:自定义反序列化字段与系统字段,设置规则一样,所以必须设置 write_only
re_password = serializers.CharField(min_length=3, max_length=16, write_only=True) class Meta:
model = models.User
# fields采用 插拔式 设置所有参与序列化与反序列化字段
fields = ('username', 'gender', 'icon', 'password', 'sex', 're_password')
extra_kwargs = {
'username': { # 系统字段不设置read_only和write_only,默认都参加
'min_length': 3,
'max_length': 10,
'error_messages': {
'min_length': '太短',
'max_length': '太长'
}
},
'gender': {
'read_only': True, # 自定义的序列化字段默认就是read_only,且不能修改,可以省略
},
'password': {
'write_only': True,
},
'sex': { # 像sex有默认值的字段,为选填字段('required': True可以将其变为必填字段)
'write_only': True,
# 'required': True
}
} # 局部全局钩子同Serializer类,是与 Meta 同缩进的
def validate_username(self, value):
if 'g' in value.lower():
raise serializers.ValidationError('名字中不能有g')
return value def validate(self, attrs):
password = attrs.get('password')
re_password = attrs.pop('re_password')
if password != re_password:
raise serializers.ValidationError({'re_password': '两次密码不一致'})
return attrs # create和update方法不需要再重写,ModelSerializer类已提供,且支持所有关系下的连表操作

总结:

  1. 序列化类继承ModelSerializer,所以需要在配置类Meta中进行配置
  2. model配置:绑定序列化相关的Model表
  3. fields配置:采用 插拔式 设置所有参与序列化与反序列化字段
  4. extra_kwargs配置: 划分系统字段为三种:只读(read_only)、只写(write_only)、可读可写(不设置) 字段是否必须:required 选填字段:在extra_kwargs进行配置,但不设置required,且有默认值
  5. 自定义序列化字段: 第一种(不提倡):在序列化类中用SerializerMethodField()来实现 第二种(提倡):在模型类中用@property来实现,可插拔
  6. 自定义反序列化字段: 同Serializer类,且规则只能在此声明中设置,或是在钩子中设置,在extra_kwargs中对其设置的无效 自定义反序列化字段与系统字段,设置规则一样,所以必须设置 write_only
  7. 局部钩子,全局钩子同Serializer类
  8. 不需要重写create和update方法

drf的序列化器的更多相关文章

  1. DRF中序列化器定义及使用

    首先需要明白序列化和反序列化的定义及作用: 序列化是将程序语言转换为JSON/XML; 反序列化是将JSON/XML转换为程序语言; 对应到Django中,序列化即把模型对象转换为字典形式, 在返回给 ...

  2. drf之序列化器的使用

    一.序列化器-Serializer 作用: 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 完成数据校验功能 3. 反序列化,把客户端发送过来的数据,经 ...

  3. 066.Python框架DRF之序列化器Serializer

    一 序列化器-Serializer 作用: 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 反序列化,把客户端发送过来的数据,经过request以后变成 ...

  4. drf序列化器serializers.SerializerMethodField()的用法

    问题描述: 为什么DRF中有时候返回的json中图片是带域名的,有时候是不带域名的呢? 解析: 带域名的结果是在view中对模型类序列化的,DRF在序列化图片的时候 会检查上下文有没有request, ...

  5. 一: DRF web应用框架基础,及序列化器的使用

    ---恢复内容开始--- 一: web 应用模式(有两种) 1: 前后端不分离(前端从后端直接获取数据) 2: 前后端分离 二: api 接口 原因一: 为了在团队内部形成共识.防止个人习惯差异引起的 ...

  6. DRF中的序列化器

    DRF中的序列化器详细应用   视图的功能:说白了就是接收前端请求,进行数据处理 (这里的处理包括:如果前端是GET请求,则构造查询集,将结果返回,这个过程为序列化:如果前端是POST请求,假如要对数 ...

  7. 写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用

    写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用 一.了解什么是DRF DRF: Django REST framework Django REST framew ...

  8. DRF(2) - 解析器,序列化组件使用(GET/POST接口设计)

    一.DRF - 解析器 1.解析器的引出 我们知道,浏览器可以向django服务器发送json格式的数据,此时,django不会帮我们进行解析,只是将发送的原数据保存在request.body中,只有 ...

  9. DRF之解析器组件及序列化组件

    知识点复习回顾一:三元运算 三元运算能够简化我们的代码,  请看如下代码: # 定义两个变量 a = 1 b = 2 # 判断a的真假值,如果为True,则将判断表达式的前面的值赋给c,否则将判断表达 ...

随机推荐

  1. 19-11-2-M

    最后一个当然要模自己辣. %%%Miemengsb ZJ一下: 三道题没有一道会的,唯一的20还是T2输出$n/2$得的 咝…… T1一看,只会暴力. T2一看,像是状压,但是我是$dpsb$,于是弃 ...

  2. Python ----键抠图

    背景 这段时间,经常有人来找我,说我是学计算机的,能不能帮他p一下证件照,我只想说,MMP的,我是学计算机的不错,可我不会ps阿. 我想了一会,python 这么火,能不能来个自动抠图,说好就干吧 介 ...

  3. 慢日志:mysqlsla

    Linux服务器收集到的慢日志文件拿到本地(Windows7)的虚拟机(CentOS6.5)中去分析.首先使用Samba工具配置CentOS和Windows文件共享,然后使用mysqlsla分析慢查询 ...

  4. python3-常用模块之openpyxl(1)

    1.创建工作簿 from openpyxl import Workbook # 创建excel对象 wb = Workbook() # 获取第一个sheet = wb.active # 单元格写入内容 ...

  5. 02.Hibernate配置文件之映射配置文件

    映射文件,即xxx.hbm.xml的配置文件 <class>标签:用来将类与数据库表建立映射关系 属性: name:类中的全路径 table:表名(如果类与表名一致,那么table属性可以 ...

  6. mysql兼容性语句

    SHOW /*!50 GLOBAL */ STATUS SHOW /*!500 GLOBAL */ STATUS SHOW /*!5000 GLOBAL */ STATUS 都报错,必须是 SHOW ...

  7. day20 作业

    目录 今日作业 1.下面这段代码的输出结果将是什么?请解释. 2.多重继承的执行顺序,请解答以下输出结果是什么?并解释. 3.什么是新式类,什么是经典类,二者有什么区别?什么是深度优先,什么是广度优先 ...

  8. RxJS 入门指引和初步应用

    作者:徐飞链接:https://zhuanlan.zhihu.com/p/25383159来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. RxJS是一个强大的React ...

  9. 修改CentOS6.5主机名引起MySQL5.6.35服务问题

    本来是心血来潮修改CentOS6.5的主机名 /****** 修改CentOS6.5默认主机名 ******/ .备份系统网络配置文件 [root@localhost ~]# cp /etc/sysc ...

  10. Dockerfile镜像制作时间同步

    1.问题描述 宿主机与容器时间相差8小时 2.原因 宿主机采用了CST时区,CST应该是指(China Shanghai Time,东八区时间)容器采用了UTC时区,UTC应该是指(Coordinat ...