­

python測試開發django-64.序列化(Serializer)

  • 2019 年 10 月 5 日
  • 筆記

前言

REST framework中的serializers與Django的Form和ModelForm類非常像。我們提供了一個Serializer類,它為你提供了強大的通用方法來控制響應的輸出,

以及一個ModelSerializer類,它為創建用於處理模型實例和查詢集的序列化程式提供了有用的快捷實現方式。

serializers.Serializer

先從一個簡單的案例開始,在apiapp目錄下編輯models.py,以創建用戶個人資訊model為例

# models.py  from django.db import models  # 作者:上海悠悠,QQ交流群:750815713    # Create your models here.  class UserPersonalInfo(models.Model):      '''用戶個人資訊'''      name = models.CharField(max_length=10, verbose_name="昵稱")  # 昵稱      sex_choices = (          (u'M', u'男'),          (u'F', u'女'),      )      sex = models.CharField(max_length=11,                             choices=sex_choices,                             verbose_name="性別",                              )      age = models.IntegerField(verbose_name="年齡",  default="", blank=True)      mail = models.EmailField(max_length=30, default="", blank=True)      create_time = models.DateField(auto_now=True, verbose_name="添加時間")

執行 makemigrations 和migrate同步資料庫

python manage.py makemigrations python manage.py migrate

Serializer是rest_framework中最簡單的序列化基類,封裝也是最低的。但是這個基類比較靈活,可以通過這個類來訂製我們需要的序列化類。 實現這個類需要重寫兩個方法,create和update。

  • create方法對應我們在使用API的時候通過POST來訪問的,因為通常通過POST來傳遞我們需要新建實例的數據。
  • update方法對應通過PUT/PATCH方法訪問API,用來新建實例或者更新已存在的實例,這取決於資料庫是否存在我們需要操作的實例。

在apiapp目錄下新建一個serializersapi.py文件,在該文件先編輯需要序列化的model,id是系統默認自帶的一個欄位。

│  manage.py  ├─apiapp  │  │  admin.py  │  │  apps.py  │  │  auth.py  │  │  models.py  │  │  serializersapi.py  │  │  tests.py  │  │  views.py  │  │  __init__.py  │  │  │  ├─migrations  │  │  │  0001_initial.py  │  │  │  0002_userpersonalinfo.py  │  │  │  __init__.py  │  └─yoyoapi      │  settings.py      │  urls.py      │  wsgi.py      │  __init__.py

在寫序列化類的時候,欄位裡面的相關參數verbose_name,blank得去掉。

# serializersapi.py  from rest_framework import serializers  from .models import UserPersonalInfo    class UserPersonalInfoSerializer(serializers.Serializer):      id = serializers.IntegerField(read_only=True)      name = serializers.CharField(max_length=10)  # 昵稱      sex_choices = (          (u'M', u'男'),          (u'F', u'女'),      )      sex = serializers.ChoiceField(choices=sex_choices                              )      age = serializers.IntegerField(default="")      mail = serializers.EmailField(max_length=30, default="")      create_time = serializers.DateField(read_only=True)        def create(self,validated_data):          return UserPersonalInfo.objects.create(**validated_data)        def update(self,instance,validated_data):          instance.name=validated_data.get('name',instance.name)          instance.sex=validated_data.get('sex',instance.sex)          instance.age=validated_data.get('age',instance.age)          instance.mail=validated_data.get('mail',instance.mail)          instance.save()          return instance

在創建ArticleSerializer的時候,創建了一些欄位,這些欄位代表Serializer類在序列化的時候和model對應的欄位。這些欄位應該和model里定義的欄位同名。

在定義的時候,指定了一些參數,這裡只用了read_only,還有其它的參數

  • write_only,required,allow_null/allow_blank,label,help_text,style,error_messages
  • read_only: 表示該欄位只能用於API的輸出,用戶並不能直接指定該欄位的值
  • write_only: 這個就和read_only相反,需要用戶指定該欄位的值
  • required: 該欄位是必需的,不能為空
  • allow_null/allow_blank: 該欄位允許為null/空
  • label: 標籤,用於對欄位顯示設置
  • help_text: 對欄位進行解釋的一段文本,用於提示
  • style: 說明欄位的類型
  • error_messages: 欄位出錯時,資訊提示

update方法中instancece參數是一個model實例,也可以是一個自定義類實例,其實model也就是一個類,只是在底層封裝了一些ORM操作。

views.py視圖

views.py編輯以下內容

# views.py  from rest_framework.response import Response  from rest_framework.views import APIView  from .models import *  from rest_framework.permissions import IsAuthenticated,AllowAny  from .serializersapi import UserPersonalInfoSerializer  # 作者:上海悠悠,QQ交流群:750815713    class UserPersonalInfoView(APIView):      '''REST framework的APIView實現獲取UserPersonalInfo表 # 作者:上海悠悠,QQ交流群:750815713'''      # authentication_classes = (TokenAuthentication,)  # token認證      # permission_classes = (IsAuthenticated,)   # IsAuthenticated 僅通過認證的用戶      permission_classes = (AllowAny,)  # 允許所有用戶        def get(self, request, format=None):          """          Return a list of all UserPersonalInfo          """          info = UserPersonalInfo.objects.all()          serializer = UserPersonalInfoSerializer(info, many=True)          return Response(serializer.data)        def post(self, request, format=None):          '''          create UserPersonalInfo          '''          verify_data = UserPersonalInfoSerializer(data=request.data)          if verify_data.is_valid():              verify_data.save()              return Response({"message": "create some data!", "data": request.data})          else:              return Response(verify_data.errors)

urls.py設置訪問路徑

# urls.py  from apiapp import views  from django.conf.urls import url    # 作者:上海悠悠,QQ交流群:750815713    urlpatterns = [      url(r'^userinfo', views.UserPersonalInfoView.as_view()),  ]

測試介面

訪問』http://127.0.0.1:8000/userinfo',post請求測試結果

POST http://127.0.0.1:8000/userinfo HTTP/1.1  User-Agent: Fiddler  Host: 127.0.0.1:8000  Content-Length: 82  Content-Type: application/json    {      "name": "yoyo",      "sex": "M",      "age": "20",      "mail": "283340479@qq.com"  }

新增成功,查看資料庫,會生成一條數據

訪問』http://127.0.0.1:8000/userinfo',get請求測試結果