三流
- 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 数据解析为二进制格式发送给前端, 也可以更以更方便的方法对数据进行验证以及数据库操作.
序列化家族
Serializer 类, 底层是序列化类,(了解原理)
ModelSerializer 类, 模型序列化类(核心)
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)
总结:
设置序列化字段, 字段名与字段类型要与处理的 model 类属性名对应(只参与序列化的类型不需要设置条件)
model 类中有的字段, 但在序列化中没有对应字段, 该类字段不参与序列化
自定义序列化字段(方法一), 字段类型为 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 类已提供, 且支持所有关系下的连表操作
总结:
序列化类继承 ModelSerializer, 所以需要在配置类 Meta 中进行配置
model 配置: 绑定序列化相关的 Model 表
fields 配置: 采用 插拔式 设置所有参与序列化与反序列化字段
extra_kwargs 配置: 划分系统字段为三种: 只读(read_only), 只写(write_only), 可读可写(不设置) 字段是否必须: required 选填字段: 在 extra_kwargs 进行配置, 但不设置 required, 且有默认值
自定义序列化字段: 第一种 (不提倡): 在序列化类中用 SerializerMethodField() 来实现 第二种(提倡): 在模型类中用 @property 来实现, 可插拔
自定义反序列化字段: 同 Serializer 类, 且规则只能在此声明中设置, 或是在钩子中设置, 在 extra_kwargs 中对其设置的无效 自定义反序列化字段与系统字段, 设置规则一样, 所以必须设置 write_only
局部钩子, 全局钩子同 Serializer 类
不需要重写 create 和 update 方法
来源: http://www.bubuko.com/infodetail-3350414.html