针对上一篇文章中的痛点,本次引入Django REST framework,使用序列化器来优化代码:

1、安装与配置:

  安装:pip install -i https://pypi.douban.com/simple/ djangorestframework

  配置:settings.py中注册子应用:INSTALLED_APPS = [ 'rest_framework',]

2、在projects子应用中新建serializer.py文件,引入序列化器,代码如下:

from rest_framework import serializers


class ProjectsSerializer(serializers.Serializer):
    id = serializers.IntegerField(label="ID", read_only=True)
    name = serializers.CharField(label="项目名称", max_length=50, min_length=5, help_text="项目名称")
    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="简要描述")

3、修改projects子应用中views.py文件代码:

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)
        # 反序列化
        serailzer = ProjectsSerializer(data=python_data)
        # 校验前端数据
        try:
            serailzer.is_valid(raise_exception=True)
        except Exception as e:
            return JsonResponse(serailzer.errors)
        # 校验成功之后的数据, 可以使用validated_data属性来获取
        # 插入数据库
        project = Projects.objects.create(**serailzer.validated_data)
        # 序列化输出
        serailzer = ProjectsSerializer(instance=project)
        return JsonResponse(data=serailzer.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(data=python_data)
        # 校验前端数据
        try:
            serialzier.is_valid(raise_exception=True)
        except Exception as e:
            return JsonResponse(serialzier.errors)
        # 更新项目
        project.name = serialzier.validated_data["name"]
        project.leader = serialzier.validated_data["leader"]
        project.programer = serialzier.validated_data["programer"]
        project.publish_app = serialzier.validated_data["publish_app"]
        project.tester = serialzier.validated_data["tester"]
        project.desc = serialzier.validated_data["desc"]
        project.save()
        serializer = ProjectsSerializer(project)
        return JsonResponse(serializer.data, status=201)

    def delete(self, request, pk):
        project = self.get_object(pk)
        project.delete()
        return JsonResponse(None, safe=False, status=204)

4、projects子应用中urls.py文件配置如下:

from django.urls import path
from projects import views


urlpatterns = [
    path('projects/', views.ProjectsList.as_view()),
    path('projects/<int:pk>/', views.ProjectsDetail.as_view())
]

5、全局urls.py文件配置如下:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),    
    path('', include('projects.urls')),
    
]

由此可见,序列化器的作用有以下几点: 

1、序列化器中定义的类属性字段往往与模型类字段一一对应
2、不对应的话,不能做序列化输出,只能用来做数据校验,判断字段长度等
3、序列化输出,将模型类转换为python中的字典或者嵌套字典的列表,传给jsonresponse,转换为json的字符串
4、可以帮我们进行校验

至此,上一篇文章(https://www.cnblogs.com/benben-wu/p/12457597.html)的代码已优化一部分,有时间再继续优化本次的代码!