針對上一篇文章中的痛點,本次引入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)的代碼已優化一部分,有時間再繼續優化本次的代碼!