序列化器:是指从数据库提取数据,转化前端所需要的数据格式并返回到前端。
反序列化器:是指把前端传回的数据,转换成数据库需要的格式,存入数据库。
DRF提供了两种序列化器:
模型序列化器:是指和模型关联的序列化器,需要引入模型来定义序列化器。
普通序列化器:是指和模型无关的序列化器,和模型无关,只是一个序列化器。
本节主要介绍模型序列化器
1 创建模型序列化器
在Applications/Examples/views下创建文件,名为:Schools.py
from rest_framework import serializers from Applications.Examples.models import Schools from rest_framework.viewsets import ModelViewSet import re class SchoolsSerializer(serializers.ModelSerializer): """ 【功能描述】模型序列化器,主要针对模型生成的序列化器。 1 临时字段 模型序列化器中可定义临时字段,用于上传用户数据,或下发从其它模型或内存中的数据。 如果上传临时字段,则设置为write_only=True 如果下发临时字段,则设置为read_only=True 2 重新定义模型字段 对于模型中已存在的字段,可以在此重新定义约束。如:手机号,座机号,可以用正则表达式来定义。 """ # 手机验证码是用于前端上传的,而不需要后端下发,故定义write_only=True sms_code = serializers.CharField(min_length=6, max_length=6, write_only=True, help_text='手机验证码') class Meta: """ 【功能描述】 1 指定模型名 2 指定需要上传或下载的模型字段名 如果所有字段全部选择,则使用fields = '__all__' 如果手工指定字段,则用元组列出要指定的字段名 """ model = Schools fields = ('id', 'name', 'email', 'phone', 'employment_rate', 'sms_code', 'teacher_quantity', 'student_quantity') extra_kwargs = { 'id': { 'read_only': True, # 用户ID是只读的,故只能读取不能填写 'help_text': '学校ID' }, 'name': { 'help_text': '学校名', 'min_length': 2, 'max_length': 10, 'error_messages': { 'min_length': '用户名不能少于两个中文字符', 'max_length': '用户名不能大于20个中文字符', }, }, 'employment_rate': { 'help_text': '就业率(%)', } } @classmethod def validate_phone(cls, value): """ 【功能描述】用于验证某个字段,则用'validate_'+字段名来命名函数,validate_<field_name> """ if not re.match(r'(?0d{2,3}[)-]?d{7,8}', value): # 正则表达式匹配座机号 raise serializers.ValidationError('不是有效的座机号') return value @classmethod def validate_employment_rate(cls, value): """ 【功能描述】用于验证某个字段,则用'validate_'+字段名来命名函数,validate_<field_name> """ if value > 100: raise serializers.ValidationError('就业率不能超过100%') if value < 0: raise serializers.ValidationError('就业率不能小于0%') return value @classmethod def validate_sms_code(cls, value): """ 【功能描述】用于处理接收的临时字段,比如验证码是否过期等操作。验证完后,在保存前要删除临时字段。 """ return value @classmethod def validate(cls, attrs): """ 【功能描述】用于同时验证多个字段 """ if attrs['teacher_quantity'] <= 0: raise serializers.ValidationError('教师人数不能小于等于0') if attrs['student_quantity'] <= 0: raise serializers.ValidationError('学生人数不能小于等于0') if attrs['teacher_quantity'] >= attrs['student_quantity']: raise serializers.ValidationError('教师人数不能大于等于学生人数') return attrs def create(self, validated_data): del validated_data['sms_code'] # 临时字段仅用于上传,保存数据库之前要删除 return Schools.objects.create(**validated_data) def update(self, instance, validated_data): """ 【功能描述】用于处理只更新部分字段的情况 """ instance.name = validated_data.get('name') # Email允许为空,前端可传可不传,如果传了,则修改,如果没传,则维持原数据 if validated_data.get('email'): instance.email = validated_data.get('email') instance.phone = validated_data.get('phone') instance.employment_rate = validated_data.get('employment_rate') instance.teacher_quantity = validated_data.get('teacher_quantity') instance.student_quantity = validated_data.get('student_quantity') instance.save() return instance class SchoolsViewSet(ModelViewSet): queryset = Schools.objects.all() serializer_class = SchoolsSerializer
2 增加视图
class SchoolsViewSet(ModelViewSet): queryset = Schools.objects.all() serializer_class = SchoolsSerializer
3 增加路由
在Examples分路由urls.py中增加一个路由:
router.register('Schools', SchoolsViewSet) # 向路由器中注册视图集
4 运行工程,测试自动生成的所有接口。共六个接口,页面如下: