zoukankan      html  css  js  c++  java
  • DRF框架serializer之ModelSerializer

    一、基本语法

    在没有使用ModelSerializer序列化器类之前,我们定义的序列化器类都需要添加对应模型类字段的很多字段,如果添加的字段特别多,那么势必会影响开发效率和代码的可读性,因此会选择一种更为简洁的序列化器类来帮我们优化框架代码,简化序列化器类中字段的创建

    常规序列化器类示例:

    from rest_framework import serializers
    from rest_framework import validators
    from .models import Projects
    
    
    class ProjectSerializer(serializers.Serializer):
        name = serializers.CharField(max_length=200, label="项目名称", help_text='项目名称',
                                     validators=[validators.UniqueValidator(queryset=Projects.objects.all(), message="项目名字段name必须唯一"),
                                                 name_is_not_contain_x],)
        leader = serializers.CharField(max_length=50, label="项目负责人", help_text='项目负责人')
        programmer = serializers.CharField(max_length=50, label="开发人员", help_text="开发人员")
        tester = serializers.CharField(max_length=50, label="测试人员", help_text="测试人员")

    使用ModelSerializer如下,已经简化了很多代码:

    from rest_framework import serializers
    from .models import Projects
    
    
    class ProjectsModelSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Projects
            fields = '__all__'

    规则总结如下:

    • 需要在Meta类中使用model类属性来指定需要按照哪一个模型类来创建
    • fields类属性指定模型类中哪些字段需要输入或输出
    • 默认id主键会添加read_only=True
    • create_time和update_time会默认添加read_only=True
    • ModelSerializer类中自带的有create和update方法,无需重写即可生效

    二、使用方法

    直接使用ModelSerializer实例化的对象替换掉原先的序列化器类对象即可

    from django.http import JsonResponse
    from django.views import View
    from django.db import connection
    import json
    from .models import Projects
    from .serializers import ProjectsModelSerializer
    
    
    class ProjectsPage(View):
        '''
        类视图
        '''
        def post(self, request):
    
            input_data = json.loads(request.body)
    
            serializer_check_obj = ProjectsModelSerializer(data=input_data)
    
            if not serializer_check_obj.is_valid():
                return JsonResponse({"code": 1, "res": "error", "msg": serializer_check_obj.errors})
    
            serializer_check_obj.save()
    
            return JsonResponse(serializer_check_obj.validated_data, status=201)

    二、反序列化校验

    1.默认全部字段输出或输入

    在Meta子类中定义类属性fields='__all__'

    fields = '__all__'

    2.指定需要输出或输入的字段

    在Meta子类中定义类属性fields=(字段1,字段2,......)

    fields = ('name', 'leader', 'programmer')

    3.排除不需要输出或输入的字段

    在Meta子类中定义类属性exclude=(字段1,字段2,......)

    exclude = ('desc', )

    4.只允许序列化输出

    在Meta子类中定义类属性read_only_fields=(字段1,字段2,......)

    read_only_fields = ('update_time', )

    5.自定义校验规则

    1).在ModelSerializer类中创建字段类的对象

    其优先级最高,如果以该类方式创建的方式很多,则应该选择普通的序列化器类来定义

    from rest_framework import serializers
    from rest_framework import validators
    from .models import Projects
    
    
    class ProjectsModelSerializer(serializers.ModelSerializer):
        name = serializers.CharField(max_length=200, label="项目名称", help_text='项目名称',
                                     validators=[validators.UniqueValidator(queryset=Projects.objects.all(),
                                                                            message="项目名字段name必须唯一")], )
    
        class Meta:
            model = Projects
            fields = '__all__'

    2).在Meta子类中定义extra_kwargs字段

    键为字段名,值为一个字典,其中键为校验项,值为校验规则

    from rest_framework import serializers
    from rest_framework import validators
    from .models import Projects
    
    
    class ProjectsModelSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Projects
            fields = '__all__'
            extra_kwargs = {
                'name': {
                    'max_length': 50,
                    'validators': [validators.UniqueValidator(queryset=Projects.objects.all(), message="项目名字段name必须唯一")]
                },
                'tester': {
                    'max_length': 200
                }
            }

    三、添加不在模型类里面而需要反序列化的字段

    • 定义字段
    • 添加字段名称到ModelSerializer序列化器类Meta子类的fields属性中
    • 在Meta子类中重写create或者update方法
    from rest_framework import serializers
    from rest_framework import validators
    from .models import Projects
    
    
    def name_is_not_contain_x(value):
        if 'X' in value.upper():
            raise serializers.ValidationError("项目名字段name不能包含x的大小写字符")
    
    
    class ProjectsModelSerializer(serializers.ModelSerializer):
    
        email = serializers.EmailField(read_only=True)
    
        class Meta:
            model = Projects
            fields = ('id', 'name', 'leader', 'programmer', 'tester', 'create_time', 'update_time', 'email')
            extra_kwargs = {
                'name': {
                    'max_length': 50,
                    'validators': [validators.UniqueValidator(queryset=Projects.objects.all(), message="项目名字段name必须唯一"),
                                   name_is_not_contain_x]
                },
                'tester': {
                    'max_length': 200
                }
            }
    
        def validate_name(self, value):
            if '项目' in value:
                raise serializers.ValidationError("项目名称name字段不能包含‘项目’字符")
            return value
    
        def validate(self, attrs):
    
            if 'A' in attrs.get('name') and 'B' in attrs.get('leader'):
                raise serializers.ValidationError("项目名称字段name不包含A的同时项目负责人字段leader也不能包含B")
            return attrs
    
        def create(self, validated_data):
            validated_data.pop('email')
    
            return super().create(validated_data)
  • 相关阅读:
    把KB转化为KB及以上单位
    php自动获取上一个月的起始时间
    CentOS 7.2mini版本下编译安装php7.4.6+MySQL5.7.14+Nginx1.18.0
    JS 根据子网掩码,网关计算出所有的IP范围
    php 在字符串指定位置插入新字符
    PHP实现文件下载
    JS 日期与时间戳相互转化
    MySQL中有关char、varchar、int、tinyint、decimal
    数据库设计三范式
    利用递归实现 两个队列实现一个栈的教程 写的超级详细小白都能看懂!
  • 原文地址:https://www.cnblogs.com/xiaogongjin/p/13287826.html
Copyright © 2011-2022 走看看