针对上一篇文章中的痛点,本次引入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)的代码已优化一部分,有时间再继续优化本次的代码!