dorian

导航

 

  序列化器:是指从数据库提取数据,转化前端所需要的数据格式并返回到前端。

  反序列化器:是指把前端传回的数据,转换成数据库需要的格式,存入数据库。

 

  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'\(?0\d{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 运行工程,测试自动生成的所有接口。共六个接口,页面如下:

 

posted on 2020-03-04 18:49  dorian  阅读(236)  评论(0编辑  收藏  举报