Django Rest_Framework初始之序列化器和反序列化

一.RESTful API規範

REST全稱是Representational State Transfer,中文意思是表述(編者注:通常譯爲表徵)性狀態轉移。 它首次出現在2000年Roy Fielding的博士論文中。

  1. RESTful是一種定義Web API接口的設計風格,尤其適用於前後端分離的應用模式中。
  2. 把後端所有的數據/文件都看成資源.,那麼接口請求數據,本質上來說就是對資源的操作了.
  3. 而對於數據資源分別使用POST、DELETE、GET、UPDATE等請求動作來表達對數據的增刪查改。
    在這裏插入圖片描述
    參考文檔:https://www.runoob.com/w3cnote/restful-architecture.html

二.序列化

api接口開發,最核心最常見的一個過程就是序列化,所謂序列化就是把數據轉換格式,序列化可以分兩個階段:

序列化: 把我們識別的數據轉換成指定的格式提供給別人。

例如:我們在django中獲取到的數據默認是模型對象,但是模型對象數據無法直接提供給前端或別的平臺使用,所以我們需要把數據進行序列化,變成字符串或者json數據,提供給別人。

響應數據[序列化]

示例:

1.定義一個模型類:

from django.db import models

# Create your models here.

class Student(models.Model):

    name = models.CharField(max_length=32,verbose_name='姓名')
    sex = models.BooleanField(default=1,verbose_name='性別')
    age = models.IntegerField(verbose_name='年齡')
    class_null = models.CharField(max_length=5,verbose_name='班級編號')
    description = models.TextField(max_length=1000,verbose_name='個性簽名')

2.創建一個序列化器類:

from rest_framework import serializers

class StudentSerializers(serializers.Serializer):

    name = serializers.CharField()
    sex = serializers.BooleanField()
    age = serializers.IntegerField()
    class_null = serializers.CharField()
    description = serializers.CharField()

3.視圖函數:

from django.http import JsonResponse
from django.views import View
from student.models import Student
from testser.seaializers import StudentSerializers


# Create your views here.

class StudentView(View):

    def get(self, request):
        student_list = Student.objects.all()

        # 使用序列化器進行數據轉換成列表的每一個成員爲字典
        # 實例化序列化器類需要傳遞三個參數:
        # StudentSerializer(instance='',data='',context={})
        # 第一個參數instance:模型對象,這個參數一般用於把模型轉成字典 進行序列化
        # 第二個參數data:客戶提交的字典數據  這個參數一般用於把字典轉成模型對象 進行校驗數據和反序列化
        # 第三個參數context:視圖中要發送給序列化器中使用的字典數據 路由或者視圖中有些數據需要傳遞到序列化器內部的方法中調用 則可以用context以字典的格式傳遞進去
        # 額外參數:many表示instance是一個模型列表 此時序列化器在轉換數據的時候可以進行循環 默認是False
        serializers = StudentSerializers(student_list, many=True)
        print(serializers.data)

        return JsonResponse(serializers.data,safe=False)
        #  如果不是字典格式就需要加一個safe=False關閉json數據的安全監測 否則會認爲數據不安全

urls中:

from django.urls import path,re_path #re_path :用於正則匹配
from testser import views


urlpatterns = [
    path('student/',views.StudentView.as_view())
]

結果:
在這裏插入圖片描述
獲取單條數據:

class StudentOneView(View):


    def get(self,request,pk):

        student_obj = Student.objects.filter(pk=pk).first()
        serializers = StudentSerializers(student_obj) # 單個對象 不再是模型列表
        print(serializers.data) #{'name': '張三', 'sex': True, 'age': 13, 'class_null': '301', 'description': 'test'}

        return JsonResponse(serializers.data)

三.反序列化

反序列化:把別人提供的數據轉換/還原成我們需要的格式。

例如:前端js提供過來的json數據,對於python而言就是字符串,我們需要進行反序列化換成模型類對象,這樣我們才能把數據保存到數據庫中。
接收數據[反序列化]

示例:

1.定義一個模型類:

class Book(models.Model):
    # 圖書模型
    title = models.CharField(verbose_name='書名', max_length=30, null=True, blank=True)
    pub_data = models.DateField(verbose_name='發佈日期')
    read = models.IntegerField(verbose_name='閱讀量', default=0)
    comment = models.IntegerField(verbose_name='評論', null=True, blank=True)

2.定義一個序列化器:

from rest_framework import serializers


class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=30)  # 裏面可以寫校驗規則
    pub_data = serializers.DateField(required=True)
    read = serializers.IntegerField(default=0, min_value=0)
    comment = serializers.IntegerField(allow_null=True)

3.視圖函數:

from django.shortcuts import render
from .serializers import BookSerializers
from django.views import View
from django.http import JsonResponse


class BookView(View):

        def get(self, request):
        # print(json.loads(request.body)) {'title': 'python', 'pub_date': '2019-10-10', 'read': 100, 'comment': 300}

        book_dict = {
                "title":"python",
                "pub_data":"2019-10-10",
                "read":-11,
                "comment":300

            }

        # 調用序列化器類進行反序列化數據校驗
        serializers = BookSerializers(data=book_dict)
        ret = serializers.is_valid()
        print('****',ret)  # True

        # 錯誤信息
        print(serializers.errors)
        '''
        {'read': [ErrorDetail(string='Ensure this value is greater than or equal to 0.', code='min_value')]}
        '''


        # 正確信息
        print(serializers.validated_data)
        '''
        OrderedDict([('title', 'python'), ('pub_data', datetime.date(2019, 10, 10)), ('read', 100), ('comment', 300)])
        '''
        return JsonResponse({'massage': 'ok'})

urls中:

from django.urls import path,re_path
from testunser import views

urlpatterns = [
    path('test_book/',views.BookView.as_view())
]

四.反序列化數據校驗

from rest_framework import serializers

# 3.外部函數設置爲驗證函數
def check_title(data):

    check_field = '123'
    if check_field in data:
        raise serializers.ValidationError(f'不能包含{check_field}!!')
    '''
    {'title': [ErrorDetail(string='不能包含123!!', code='invalid')]}
    '''

class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=30,validators=[check_title])  # 裏面可以寫校驗規則
    pub_data = serializers.DateField(required=True)
    read = serializers.IntegerField(default=0, min_value=0)
    comment = serializers.IntegerField(allow_null=True)

    # 1.單個字段校驗
    def validate_title(self, attrs):

        if '789' in attrs:
            raise serializers.ValidationError('不能包含123!!!!')
        return attrs

    '''
    {'title': [ErrorDetail(string='不能包含123!!!!', code='invalid')]}
    '''

    # 2.多個字段校驗
    def validate(self, attrs):
        read = attrs.get('read')
        comment = attrs.get('comment')

        if comment > read:
            raise serializers.ValidationError('評論量不能大於閱讀量!!!')
        return attrs

    '''
    {'non_field_errors': [ErrorDetail(string='評論量不能大於閱讀量!!!', code='invalid')]}
    '''
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章