• django框架学习三:djangorestframework中序列化器的优化:添加单字段、多字段、自定义函数的校验


    serializer.py文件的优化,此阶段添加了对字段的校验以及序列化器自带的create方法和update方法:

    # -*- coding: utf-8 -*-
    # @Time    : 2020/3/10 20:07
    # @Author  : benben
    # @File    : serializer.py
    from rest_framework import serializers
    from rest_framework.validators import UniqueValidator
    
    from .models import Projects
    
    # 创建自定义校验器
    # 第一个参数为字段的值
    
    
    def is_unique_project_name(name):
        if '项目' not in name:
            raise serializers.ValidationError('项目名称中必须包含"项目"')
    
    
    class ProjectsSerializer(serializers.Serializer):
        id = serializers.IntegerField(label="ID", read_only=True)
        name = serializers.CharField(label="项目名称", max_length=50, min_length=5, help_text="项目名称",
                                     validators=[UniqueValidator(queryset=Projects.objects.all(), message="项目名称已存在"),
                                                 is_unique_project_name])
        leader = serializers.CharField(label="负责人", max_length=50, help_text='负责人')
        tester = serializers.CharField(label="测试人员", max_length=50, help_text="测试人员")
        programer = serializers.CharField(label="开发人员", max_length=50, help_text="开发人员")
        publish_app = serializers.CharField(label="发布应用", max_length=100, help_text="发布应用")
        desc = serializers.CharField(label="简要描述", allow_null=True, allow_blank=True, default='', help_text="简要描述")
    
        # 单字段校验器
        # validate_字段名
        # 字段定义时的限制(包含validators列表条目从左到右进行校验) -> 单字段的校验(validate_字段名) -> 多字段联合校验(validate)
        def validate_name(self, value):
            if not value.endswith("项目"):
                raise serializers.ValidationError('项目名称必须以"项目"结尾')
            return value
    
        # 多字段校验器
        def validate(self, attrs):
            if "benben" not in attrs['tester'] and "benben" not in attrs["leader"]:
                raise serializers.ValidationError("benben必须是项目负责人或者测试人员")
            return attrs
    
        # 新增项目
        def create(self, validated_data):
            return Projects.objects.create(**validated_data)
    
        # 修改项目
        def update(self, instance, validated_data):
            instance.name = validated_data['name']
            instance.leader = validated_data['leader']
            instance.tester = validated_data['tester']
            instance.programer = validated_data['programer']
            instance.publish_app = validated_data['publish_app']
            instance.desc = validated_data['desc']
            instance.save()
            return instance

    views.py文件优化:使用serialzer.save(),自动调用序列化器中的create方法和update()方法:

    import json
    from django.views import View
    from django.http import JsonResponse, Http404
    from .models import Projects
    from .serializer import ProjectsSerializer
    
    
    class ProjectsList(View):
        def get(self, request):
            # 从数据库中读取所有的项目
            projects = Projects.objects.all()
            # 序列化输出, 将查询集传给序列化器的instance参数
            # 由于是查询多条记录,所以需要设置many=True
            serializer = ProjectsSerializer(instance=projects, many=True)
            # 由于返回的是嵌套字典的列表,所以需要设置safe=False
            return JsonResponse(data=serializer.data, safe=False)
    
        def post(self, request):
            # 获取前端提交的信息
            json_data = request.body.decode("utf-8")
            # 将json字符串转换为python中的dict
            python_data = json.loads(json_data)
            # 反序列化
            serializer = ProjectsSerializer(data=python_data)
            # 校验前端数据
            try:
                serializer.is_valid(raise_exception=True)
            except Exception as e:
                return JsonResponse(serializer.errors)
            # 校验成功之后的数据, 可以使用validated_data属性来获取
            # 1. 如果在创建序列化器对象的时候, 只给data传参, 那么调用save()方法,
            # 实际调用的就是序列化器对象的create()方法
            # serializer.save(user="孤鹰", age=16)
            serializer.save()
            # 3. 将模型类对象转化为字典, 然后返回
            # 序列化
            return JsonResponse(serializer.data, status=201)
    
    
    class ProjectsDetail(View):
        def get_object(self, pk):
            try:
                return Projects.objects.get(id=pk)
            except Projects.DoesNotExist:
                return Http404
    
        def get(self, request, pk):
            project = self.get_object(pk)
            serailzer = ProjectsSerializer(instance=project)
            return JsonResponse(serailzer.data)
    
        def put(self, request, pk):
            project = self.get_object(pk)
            # 获取前端提交的信息
            json_data = request.body.decode("utf-8")
            # 将json字符串转换为python中的dict
            python_data = json.loads(json_data)
            serialzier = ProjectsSerializer(instance=project, data=python_data)
            # 校验前端数据
            try:
                serialzier.is_valid(raise_exception=True)
            except Exception as e:
                return JsonResponse(serialzier.errors)
            # 更新项目
            # 在创建序列化器对象时, 如果同时给instance和data传参
            # 那么调用save()方法, 会自动化调用序列化器对象的update
            serialzier.save()
            return JsonResponse(serialzier.data, status=201)
    
        def delete(self, request, pk):
            project = self.get_object(pk)
            project.delete()
            return JsonResponse(None, safe=False, status=204)

    models.py文件和urls.py文件代码未更新,继续使用上一篇文章中的代码即可!

  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    每天一点点之 taro 框架开发
    每天一点点之 taro 框架开发
    每天一点点之 taro 框架开发
    WIN10怎么查看端口,并杀死进程
    每天一点点之 taro 框架
    taro编译的时候报 exports.pRimraf = util_1.promisify(rimraf); 错误
    新部署到服务器 报 The requested URL /home/profession was not found on this server. 错误
    ubuntu16.04 重置mysql密码
    SQLSTATE[HY000] [2002] No such file or directory
  • 原文地址:https://www.cnblogs.com/benben-wu/p/12489979.html
Copyright © 2020-2023  润新知