django 3.2.13
一、序列化和反序列化
安装:
pip install djangorestframework
序列化:序列化就是从数据库里面取出数据—>并且把数据格式改为能直接返回的格式(如json、xml)。补充:django rest引入这一步的目的就是为了简便格式的处理,这样能少写很多繁琐的代码。
反序列化:反序列化就是用户向服务器发送参数(如json)—>变为数据库可以识别的,中间还要经过数据的验证
1.继承serializers.Serializer
1.1 初始化配置
过程:对应模型models.py里面的模型在serializers.py进行创建,此步为了能够让serializers识别模型
App/models.py
class User(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=20)
def __str__(self):
return self.name
App/serializers.py
注意:此处写的语法规则与定义模型时类似但也有不同,如下面是此参数说明
class UserSerializer(serializers.Serializer):
id = serializers.IntegerField(label='ID')
name = serializers.CharField(max_length=20,label='名称')
字段 | 字段构造方式 |
---|---|
BooleanField | BooleanField() |
NullBooleanField | NullBooleanField() |
CharField | CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) |
EmailField | EmailField(max_length=None, min_length=None, allow_blank=False) |
RegexField | RegexField(regex, max_length=None, min_length=None, allow_blank=False) |
SlugField | SlugField(maxlength=50, min_length=None, allow_blank=False)正则字段,验证正则模式 [a-zA-Z0-9-]+ |
URLField | URLField(max_length=200, min_length=None, allow_blank=False) |
UUIDField | UUIDField(format=‘hex_verbose’)format:① ‘hex_verbose’ 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a"② ‘hex’ 如 "5ce0e9a55ffa654bcee01238041fb31a"③’int’ - 如: "123456789012312313134124512351145145114"④’urn’ 如: “urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a” |
IPAddressField | IPAddressField(protocol=‘both’, unpack_ipv4=False, **options) |
IntegerField | IntegerField(max_value=None, min_value=None) |
FloatField | FloatField(max_value=None, min_value=None) |
DecimalField | DecimalField(max_digits, decimal_places, coerce_to_string=None,max_value=None,min_value=None)max_digits: 最多位数decimal_palces: 小数点位置 |
DateTimeField | DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None) |
DateField | DateField(format=api_settings.DATE_FORMAT, input_formats=None) |
TimeField | TimeField(format=api_settings.TIME_FORMAT, input_formats=None) |
DurationField | DurationField() |
ChoiceField | ChoiceField(choices)choices与Django的用法相同 |
MultipleChoiceField | MultipleChoiceField(choices) |
FileField | FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
ImageField | ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
ListField | ListField(child=, min_length=None, max_length=None) |
DictField | DictField(child=) |
参数名称 | 作用 |
---|---|
max_length | 最大长度 |
min_lenght | 最小长度 |
allow_blank | 是否允许为空 |
trim_whitespace | 是否截断空白字符 |
max_value | 最小值 |
min_value | 最大值 |
read_only | 表明该字段仅用于序列化输出,默认False |
write_only | 表明该字段仅用于反序列化输入,默认False |
required | 表明该字段在反序列化时必须输入,默认True |
default | 反序列化时使用的默认值 |
allow_null | 表明该字段是否允许传入None,默认False |
validators | 该字段使用的验证器 |
error_messages | 包含错误编号与错误信息的字典 |
label | 用于HTML展示API页面时,显示的字段名称 |
help_text | 用于HTML展示API页面时,显示的字段帮助提示信息 |
1.2 序列化
核心:Serializer(instance=None, data=empty, **kwarg) # 给instance值就是使用序列化,给data值就是使用反序列化
新建:Serializer(data=requestData)
更新:Serializer(instance, data=requestData)
获取:Serializer(instance)
代码:
user= User.objects.get(id=2)
serializer = UserSerializer(instance=user)# 进行序列化
print(serializer.data)#{'a':55,'c':999}
1.2.1 删除不想要的字段
解释:当serializer.data中某些字段不想要时,就可以向删除字典内容一样将其删除
user= User.objects.get(id=2)
serializer = UserSerializer(instance=user)# 进行序列化
a = serializer.data
del a['username']
# 这时候返回a就可以,里面自然不会包括username字段
1.2.2 转换格式
注意:如果要被序列化的是包含多条数据的查询集,添加many=True,如:serializer = UserSerializer(instance=user,many=True)
from testWeb.models import User
from testWeb.serializers import UserSerializer
user= User.objects.get(id=2)
serializer = UserSerializer(instance=user)# 进行序列化
print(serializer.data) # 获取序列化从数据库提取出来的数据
# 遇到关联的对象数据不是只有一个,而是包含多个数据,添加many=True
serializer = UserSerializer(instance=user,many=True)# 进行序列化
# 使用外键的对象,则需要用外键对应serializer.py里面的序列类
① 错例子
o = Student.objects.get(id=3).foreign # Student关联Teacher
oo = StudentSerializer(o) # 此处有问题应该为Teacher关联类
② 正确例子
o = Student.objects.get(id=3).foreign # Student关联Teacher
oo = TeacherSerializer(o) # 正确
外键问题
缘由:django rest在把models模型转换为serializer序列类时,大部分属性都和model一样,但是外键这里进行单独处理
- 值为id
h = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
- 值为models.py自己设置的__str__的返回值
h = serializers.StringRelatedField(label='图书')
- 值关联对象的数据值
h = BookInfoSerializer() # 此为关联对象
1.3 反序列化
1.3.1 验证
验证流程:
>>> data = {"name":"5559"}
>>> response = TeacherSerializer(data=data)
>>> response.is_valid()
True
>>> response.save()
<Teacher: 5559>
# response.errors 查看报错内容
>>> response.errors
{'name': [ErrorDetail(string='该字段是必填项。', code='required')]}
# 验证报错
>>> response.is_valid(raise_exception=True) # 当发送错误直接报错
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\Loser\AppData\Local\Programs\Python\Python38\lib\site-packages\rest_framework\serializers.py", line 235, in is_valid
raise ValidationError(self.errors)
rest_framework.exceptions.ValidationError: {'name': [ErrorDetail(string='该字段是必填项。', code='required')]}
验证规则:
- validate_<自己定义的名字>
serializers.py
class TeacherSerializer(serializers.Serializer):
id = serializers.IntegerField(label='ID')
name = serializers.CharField(max_length=20,label='名称')
def validate_name(self,value):
if value != '853':
raise serializers.ValidationError("853失败")
else:
return True # 必须要提供返回值
>>> data ={ "name":"859"}
>>> o = TeacherSerializer(data=data)
>>> o.is_valid(raise_exception=True)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\Loser\AppData\Local\Programs\Python\Python38\lib\site-packages\rest_framework\serializers.py", line 235, in is_valid
raise ValidationError(self.errors)
rest_framework.exceptions.ValidationError: {'name': [ErrorDetail(string='853失败', code='invalid')]}
- validate(多字段一同验证)
serializers.py
class TeacherSerializer(serializers.Serializer):
id = serializers.IntegerField(label='ID')
name = serializers.CharField(max_length=20,label='名称')
def validate(self,data):
if data['name'] != '853':
raise serializers.ValidationError("853失败")
else:
return True # 必须要提供返回值
>>> data ={ 'name':"859"}
>>> o = TeacherSerializer(data=data)
>>> o.is_valid(raise_exception=True)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\Loser\AppData\Local\Programs\Python\Python38\lib\site-packages\rest_framework\serializers.py", line 235, in is_valid
raise ValidationError(self.errors)
rest_framework.exceptions.ValidationError: {'non_field_errors': [ErrorDetail(string='853失败', code='invalid')]}
1.3.2 转换格式
解释:当数据被验证后,需要自己写入create()和update()函数,当你执行save()时,其会帮你判断执行create()还是update(),ModelSerializer包含默认的create()和update()的实现
# save()函数源码
def save(self, **kwargs):
validated_data = {**self.validated_data, **kwargs}
if self.instance is not None:
self.instance = self.update(self.instance, validated_data)
assert self.instance is not None, (
'`update()` did not return an object instance.'
)
else:
self.instance = self.create(validated_data)
assert self.instance is not None, (
'`create()` did not return an object instance.'
)
# create()自定义返回一个数据给save()
def create(self, validated_data):
"""新建"""
return Teacher(**validated_data)
# update()自定义返回一个数据给save()
def update(self, instance, validated_data):
"""更新,instance为要更新的对象实例"""
instance.btitle = validated_data.get('btitle', instance.btitle)
instance.bpub_date = validated_data.get('bpub_date', instance.bpub_date)
instance.bread = validated_data.get('bread', instance.bread)
instance.bcomment = validated_data.get('bcomment', instance.bcomment)
return instance
2.继承serializers.ModelSerializer
介绍:与Serializer功能一致,但代码更精简(常用)
区别:
- 基于模型类自动生成一系列字段
- 基于模型类自动为Serializer生成validators,比如unique_together
- 包含默认的create()和update()的实现
2.1 初始化配置(区别)
过程:基于模型类自动生成一系列字段
App/models.py
class Teacher(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=20)
def __str__(self):
return self.name
App/serializers.py
class TeacherSerializer(serializers.ModelSerializer):
"""图书数据序列化器"""
class Meta:
model = Teacher
fields = '__all__'
指定字段:
- fields:来明确字段,__all__表名包含所有字段或者写明具体哪些字段
class Meta:
model = Teacher
fields = ('id', 'like', 'go')
- exclude:明确排除改字段别的都要
class Meta:
model = Teacher
exclude = ('image',)
- extra_kwargs:添加或修改原有的选项参数
extra_kwargs = {
'go': {'min_value': 5, 'required': True},
'like': {'min_value': 5, 'required': True},
}
- 自定义添加
class StudentSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = '__all__'
name = serializers.CharField(max_length=20, label='名称') # 自己给其新增
extra_kwargs={
'passwd':{'required':False},
'time':{'required':False}
}
2.2 序列化(区别)
解释:大体类似无明显区别
2.3 反序列化(区别)
解释:ModelSerializer额外提供了默认的create()和update()的方法,用来新建与更新数据,而serializers.Serializer也有默认的create()和update()的方法,但是没有任何代码需要自己书写
使用:
① save
>>> data = {"name":"85999"}
>>> r = TeacherSerializer(data=data)
>>> r.is_valid()
True
>>> r.save()
<Teacher: 85999>