django框架学习四:引入djangorestframework中ModelSerializer

ModelSerializer的优点:
1、不用手动写序列化输出的字段
2、自动创建create和update方法
代码如下:
def is_unique_project_name(name):
    if '项目' not in name:
        raise serializers.ValidationError('项目名称中必须包含"项目"')


class ProjectsModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Projects
        # 所有序列化输出的字段
        fields = "__all__"
        # 指定需要序列化输出的字段
        # fields = ("id", "name", "leader", "tester")
        # 指定不需要序列化输出的字段
        # exclude = ('publish_app', 'desc')
        # 指定只读字段
        # read_only_fields = ('tester', 'leader')
        # 自定义添加字段属性
        extra_kwargs = {
            "name": {
                # "write_only": True,
                "error_messages": {
                    "max_length": "最长只能输入50个字符"
                 },
                "validators": [UniqueValidator(Projects.objects.all(), message="项目名称不能重复"), is_unique_project_name]
            }
        }
        
    # 单字段校验
    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

views.py文件中的代码,将原来的ProjectsSerializer改为ProjectsModelSerializer,其它代码不用改动:

import json
from django.views import View
from django.http import JsonResponse, Http404
from .models import Projects
from .serializers import ProjectsModelSerializer


class ProjectsList(View):
    def get(self, request):
        # 从数据库中读取所有的项目
        projects = Projects.objects.all()
        # 序列化输出, 将查询集传给序列化器的instance参数
        # 由于是查询多条记录,所以需要设置many=True
        serializer = ProjectsModelSerializer(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 = ProjectsModelSerializer(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 = ProjectsModelSerializer(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 = ProjectsModelSerializer(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)
原文地址:https://www.cnblogs.com/benben-wu/p/12492978.html