Django 原生 serializer (序列化)
- 導入模塊 from django.core.serializers import serialize
- 獲取 queryset
- 對 queryset 進行序列化
- 將序列化之后的數據,返回給客戶端
首先,設計url, 先只定義GET和POST接口
from django.urls import path from DrfOne import views urlpatterns = [ path('books/', views.BookView.as_view()), ]
再定義幾個models

1 from django.db import models 2 3 4 class Publish(models.Model): 5 nid = models.AutoField(primary_key=True) 6 name = models.CharField("出版社名", max_length=32) 7 address = models.CharField("出版社位置", max_length=32) 8 email = models.EmailField("郵箱") 9 10 def __str__(self): 11 return self.name 12 13 14 class Author(models.Model): 15 nid = models.AutoField(primary_key=True) 16 name = models.CharField("姓名", max_length=31) 17 age = models.IntegerField("年齡") 18 19 def __str__(self): 20 return self.name 21 22 23 class Book(models.Model): 24 nid = models.AutoField(primary_key=True) 25 title = models.CharField("書名", max_length=32) 26 price = models.DecimalField("價格", max_digits=5, decimal_places=2) 27 publish = models.ForeignKey(to="Publish", on_delete=models.CASCADE) 28 authors = models.ManyToManyField(to="Author") 29 30 def __str__(self): 31 return self.title
使用
from django.shortcuts import render, HttpResponse from rest_framework.views import APIView # 1.導入模塊 from django.core.serializers import serialize class CourseView(APIView): def get(self, request): # 2.獲取queryset course_obj = models.Course.objects.all() # 3.序列化 serialized_data = serialize("json", course_obj) print(serialized_data) # 4.將序列化之后的數據返回 return HttpResponse(serialized_data)
序列化組件serializer的使用
Serializer
GET接口設計(獲取所有數據)
- 導入模塊
- 建立一個序列化類
- 獲取 queryset
- 開始序列化
- 獲取序列化后的數據,返回給客戶端
from rest_framework.views import APIView # 1.導入模塊 from rest_framework import serializers # drf重新封裝之后的Response基於TemplateResponse類型, # 可以將未處理的內容通過內容協商來決定返回給客戶端的正確內容形式 from rest_framework.response import Response from DrfOne import models # 2.創建一個序列化類,字段類型不一定要跟models的字段一樣 class BookSerializer(serializers.Serializer): # id一般情況不用寫 # nid = serializers.CharField(max_length=32) title = serializers.CharField(max_length=32) price = serializers.DecimalField(max_digits=5, decimal_places=2) # 外鍵字段,顯示__str__方法的返回值 publish = serializers.CharField() # 多對多字段, 執行get_字段名 方法,手動獲取數據 author_list = serializers.SerializerMethodField() def get_author_list(self, book_obj): # 第二個參數隨意 author_list = list() for author in book_obj.authors.all(): author_list.append(author.name) return author_list class BookView1(APIView): def get(self, request): # 3.獲取queryset book_objs = models.Book.objects.all() # 4.通過序列化類進行序列化 serialized_obj = BookSerializer(book_objs, many=True) # print(serialized_obj) # 5.獲取序列化之后的數據,返回給客戶端 return Response(serialized_obj.data)
POST接口設計
- 導入模塊
- 建立一個序列化類
- 獲取客戶端請求數據
- 開始序列化
- 寫入數據庫
- 將插入的對象返回給客戶端
請注意,因為多對多關系字段是我們自定義的,而且必須這樣定義,返回的數據才有意義,而用戶插入數據的時候,serializers.Serializer沒有實現create,我們必須手動插入數據,就像這樣:
# 1.導入模塊 from rest_framework import serializers from rest_framework.views import APIView # drf重新封裝之后的Response基於TemplateResponse類型, # 可以將未處理的內容通過內容協商來決定返回給客戶端的正確內容形式 from rest_framework.response import Response from DrfOne import models # 2.創建一個序列化類,字段名和字段類型不一定要跟models的字段一樣 class BookSerializer(serializers.Serializer): # id一般情況不用寫 # nid = serializers.CharField(max_length=32) title = serializers.CharField(max_length=32) price = serializers.DecimalField(max_digits=5, decimal_places=2) # 外鍵字段,顯示__str__方法的返回值 publish = serializers.CharField() # 僅讀字段read_only=True,source是該字段顯示出版社地址 publish_address = serializers.CharField(max_length=32, read_only=True, source="publish.address") publish_email = serializers.CharField(max_length=32, read_only=True, source="publish.email") # 多對多字段, 執行get_字段名 方法,手動獲取數據 author_list = serializers.SerializerMethodField() def get_author_list(self, book_obj): # 第二個參數隨意 author_list = list() for author in book_obj.authors.all(): author_list.append(author.name) return author_list def create(self, validated_data): # 創建時調用 validated_data['publish_id'] = validated_data.pop('publish') book = models.Book.objects.create(**validated_data) return book def update(self, instance, validated_data): # 更新數據會調用該方法 instance.title = validated_data.get('title', instance.title) instance.publishDate = validated_data.get('publishDate', instance.publishDate) instance.price = validated_data.get('price', instance.price) instance.publish_id = validated_data.get('publish', instance.publish.nid) instance.save() return instance class BookView(APIView): def get(self, request): pass def post(self, request): # 3.獲取客戶端的數據 client_data = request.data # 4.序列化,默認many=False單條數據 verified_data = BookSerializer(data=client_data) # 對數據進行驗證 if verified_data.is_valid(): # 5.寫入數據庫 book = verified_data.save() authors = models.Author.objects.filter(nid__in=request.data["authors"]) book.authors.add(*authors) # 6.將插入的對象數據返回 return Response(verified_data.data) # 驗證失敗返回錯誤信息 return Response(verified_data.errors)
從上面可以看出:
- serializers.Serializer 無法插入數據,只能自己實現。
- 字段太多,不能自動序列化
這樣就會非常復雜化程序,如果我希望序列化類自動插入數據呢?
這也就有了 ModelSerializer
ModelSerializer
ModelSerializer 類似於form組件里的 ModelForm
from rest_framework import serializers from rest_framework.views import APIView class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = "__all__" extra_kwargs = { # 僅寫 "publish": {'write_only': True}, "authors": {'write_only': True}, } publish_name = serializers.CharField(max_length=32, read_only=True, source="publish.name") publish_address = serializers.CharField(max_length=32, read_only=True, source="publish.address") author_name = serializers.SerializerMethodField() def get_author_name(self, book_obj): author_list = list() for author in book_obj.authors.all(): # 注意列表添加字段,author.name而不是author author_list.append(author.name) return author_list
這樣看起來簡單多了!
get(單條數據)、put(改)、delete(刪) 接口設計
設計url
from django.urls import path, re_path from DrfOne import views urlpatterns = [ path('books/', views.BookView.as_view()), re_path("books/(\d+)/", views.BookFilterView.as_view()), ]
視圖設計
class BookFilterView(APIView): def get(self, request, nid): # 獲取queryset book_obj = models.Book.objects.get(pk=nid) # 序列化 serialized_data = BookSerializer(book_obj) # 返回數據 return Response(serialized_data.data) def put(self, request, nid): # 獲取queryset book_obj = models.Book.objects.get(pk=nid) # 序列化, 根據instance是確認是否是更新, many默認為False可以不寫 verified_data = BookSerializer(data=request.data, instance=book_obj, many=False) if verified_data.is_valid(): verified_data.save() # 返回數據 return Response(verified_data.data) return Response(verified_data.errors) def delete(self, request, nid): models.Book.objects.get(pk=nid).delete() return Response("")
~>.<~