文章目录
前言
drf框架中serializers(序列化与反序列化)
一、serializers是什么?
每个语言都有自己的数据类型,不同语言要想数据传输,就必须指定一种各种语言通用的数据类型,如json,xml等等
序列化器允许把像查询集和模型实例这样的复杂数据转换为可以轻松渲染成JSON,XML或其他内容类型的原生Python类型
二、serializers使用
1.serializers.Serializer使用
from django.contrib.auth.hashers import make_password
from rest_framework import serializers
from sers.models import StudentSerModel
class StudentSerializer(serializers.Serializer):
""" 学生信息序列化器 """
# 1.转换的字段声明
# 字段= serializer.字段类型(选项=选项值;)
id = serializers.IntegerField(read_only=True) # 在客户端提交的数据【反序列化阶段不会要求id字段】
name = serializers.CharField(required=True) # required=True 反序列化阶段必填
sex = serializers.BooleanField(default=True) # default=True 反序列化阶段,客户端没有提交,则默认为True
age = serializers.IntegerField(max_value=100, min_value=0)
description = serializers.CharField(allow_null=True, allow_blank=True) # 允许客户端不填写内容(None),或值为""
# validators 外部验证函数选项,值是一个列表,列表得到成员是函数名,不能是字符串!!!
classmate = serializers.CharField(validators=[check_classmate])
# 2. 如果序列化器集成的是ModelSerializer,则需要声明调用的模型信息
# 3.验证代码的对象方法
# def validate(self, attrs): # validate是规定的
# pass
# return attrs
#
# def validate_id(self, data): # 方法名的格式必须以 validate_<字段名>为名称,否则序列化器不识别
# pass
# return data
def validate_name(self, data):
""" 验证单个字段
validate开通的方法,会自动被is_valid调用
"""
if data in ['ddd', 'zzz']:
raise serializers.ValidationError(detail='学生姓名不能是ddd或zzz', code='validate_name')
# 验证成功以后,必须返回数据,否则最终的验证结果中,就不会出现这个数据了
return data
def validate(self, attrs):
"""
验证来自客户端的所有数据
类似会员注册的密码和确认密码,就只能在validate方法中校验
validate是固定的方法
参数:attrs,是序列化器实例化是的data选项数据
"""
if attrs['classname'] == 111 and attrs['sex']:
raise serializers.ValidationError(detail='报错信息', code='validate')
return attrs
# # 4. 模型操作的方法
def create(self, validated_data): # 添加数据操作,添加数据以后,就自动是想了从字典变为模型对象的过程
"""
添加数据
方法名固定为create,固定参数validated_data就是验证成功以后的结果
"""
student = StudentSerModel.objects.create(**validated_data)
return student
def update(self, instance, validated_data): # 更新数据的操作,更新数据以后,就自动实现了从字典变成模型对象的过程
"""
更新数据
方法名固定为update,
固定参数instance,实例化序列化器对象,必须传入的模型对象
固定参数validated_data就是验证成功以后的结果
更新数据以后,就自动实现了从字典变为模型对象的过程
"""
# instance.name = validated_data['name']
# instance.age = validated_data['age']
# instance.sex = validated_data['sex']
# instance.classmate = validated_data['classmate']
# instance.description = validated_data['description']
for key, value in validated_data.items():
setattr(instance, key, value)
instance.save()
return instance
2.serializers.ModelSerializer使用
class StudentModelSerializer(serializers.ModelSerializer):
""" 学生信息序列化器 """
# 1.转换的字段声明
# 字段= serializer.字段类型(选项=选项值;)
# 2.如果当前序列化器继承的是ModelSerializer,则组药声明调用的模型信息
# 必须给Mate声明2个属性
class Meta:
model = StudentSerModel
fields = '__all__' # 必填,可以是字符串和列表/元组
# read_only_fields = [] # 选填,只读字段列表,表示设置这里的字段只会在序列化阶段采用
extra_kwargs = { # 选填,字段额外选项声明
'age': {
'max_value': 100,
'min_value': 6,
'error_messages': {
'min_value': '年龄最小值不能小于6',
'max_value': '年龄最大值不能大于100',
},
}
}
exclude = ['description'] # 排除,与fields互斥
# 3.验证代码的对象方法
def create(self, validated_data):
# 密码加密
validated_data['password'] = make_password(validated_data['password'])
super().create(validated_data)
3.view视图
from django.http import JsonResponse
from django.views import View
from sers.models import StudentSerModel
from sers.serializers import StudentSerializer
class Student(View):
def get(self, request):
""" 序列化器-序列化阶段的调用 """
# 1.获取数据集
student_list = StudentSerModel.objects.all()
# 2.实例化序列化器,得到序列化对象
serializer = StudentSerializer(instance=student_list, many=True)
# 3.调用序列化对象的data属性方法获取转换后的数据
data = serializer.data
# 4.响应数据
return JsonResponse(data=data, status=200, safe=False)
def post(self, request):
""" 反序列化器- 采用字段选项来验证数据"""
# 1.接收客户端提交的数据
data = request.POST
# 1.1 实例化序列化器,获取序列化对象
# 默认的序列化器必须传递所有required的字段,否则回抛出验证异常。但是我们可以使用partial参数来允许部分字段更新
# serializer = StudentSerializer(instance = instance, data=data, partial=True)
serializer = StudentSerializer(data=data)
# 1.2 调用序列化器进行数据验证
serializer.is_valid(raise_exception=True)
# 1.3 获取验证以后的结果
data = serializer.data
# 2.操作数据库,save()方法调用create()方法
# request.user是django中记录当前登录用户的模型对象,可以在save中,传递一些不需要验证的数据到模型里面
# serializer.save(owner=request.user)
serializer.save()
# 3.返回结果
return JsonResponse(data=data, status=200)