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文件代码未更新,继续使用上一篇文章中的代码即可!