2020-12-1402 drf之restful規(guī)范,序列化組件,Request類(lèi)

昨日回顧

1、web開(kāi)發(fā)模式

-前后端混合開(kāi)發(fā)
-前后端分離開(kāi)發(fā)

2、api接口

3、postman的使用(莫伊發(fā)送http請(qǐng)求的工具)

-對(duì)地址要求嚴(yán)格
-攜帶get數(shù)據(jù)
-攜帶post數(shù)據(jù)(格式)
-攜帶請(qǐng)求頭

4、drf:djangorestframework是一個(gè)django的一個(gè)app,更快速的在django框架上的寫(xiě)接口

-pip3 install djangorestframework

今日內(nèi)容

1、restful規(guī)范

-1)、REST與技術(shù)無(wú)關(guān),代表的是一種軟件架構(gòu)風(fēng)格,REST是Representational State Transfer:表征性狀態(tài)轉(zhuǎn)移
    REST從資源的角度類(lèi)審視整個(gè)網(wǎng)絡(luò),它將分布在網(wǎng)絡(luò)中某個(gè)節(jié)點(diǎn)的資源通過(guò)URL進(jìn)行標(biāo)識(shí),客戶端應(yīng)用通過(guò)URL來(lái)獲取資源的表征,獲得這些表征致使這些應(yīng)用轉(zhuǎn)變狀態(tài)
    所有的數(shù)據(jù),不過(guò)是通過(guò)網(wǎng)絡(luò)獲取的還是操作(增刪查改)的數(shù)據(jù),都是資源,將一切數(shù)據(jù)視為資源,是REST區(qū)別于其他架構(gòu)風(fēng)格的最本質(zhì)的屬性
    對(duì)于REST這種面向資源的架構(gòu)風(fēng)格,有人提出一種全新的結(jié)構(gòu)理念,即:面向資源架構(gòu)
-2)、web API接口的設(shè)計(jì)風(fēng)格,尤其適用于前后端分離的應(yīng)用模式中
-3)、于語(yǔ)言,平臺(tái)無(wú)關(guān),任何框架都可以寫(xiě)出符合restful規(guī)范的api接口
-4)、規(guī)范:10條
    -1、數(shù)據(jù)的安全保障:url鏈接一般都采用http協(xié)議進(jìn)行傳輸
    -2、接口特征表現(xiàn):api關(guān)鍵字標(biāo)識(shí)
        -API與用戶的通信協(xié)議,總是使用https協(xié)議 ,也即是加密傳輸 詳情:http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
        -https://api.baidu.com/books/
        -https://www.baidu.com/api/books/
    -3、多版本共存:url鏈接中標(biāo)識(shí)接口版本
        -https://api.baidu.com/v1/books/
        -https://api.baidu.com/v2/books/
    -4、數(shù)據(jù)即是資源,軍使用名詞(可復(fù)數(shù))
        -接口一般都是完成前臺(tái)數(shù)據(jù)的交互,交互的數(shù)據(jù)我們稱(chēng)之為資源
        -一般提倡用醫(yī)院的附屬形式,不要用動(dòng)詞
        -查詢(xún)所有圖書(shū)
            -https://api.baidu.com/books/
            -https://api.baidu.com/get_all_books/  #錯(cuò)誤示范
            -https://api.baidu.com/delete_user/  #錯(cuò)誤示范
            -https://api.baidu.com/user/  #刪除用戶的示例,疑問(wèn)一下,這到底是刪還是查?可以通過(guò)請(qǐng)求方式來(lái)區(qū)分
    -5、資源操作由請(qǐng)求方式?jīng)Q定:
        -https://api.baidu.com/books/    # get請(qǐng)求:獲取所有書(shū)
        -https://api.baidu.com/books/1    # get請(qǐng)求:獲取主鍵為1的書(shū)
        -https://api.baidu.com/books/    # post請(qǐng)求:新增一本書(shū)
        -https://api.baidu.com/books/1   # put請(qǐng)求:整體修改主鍵為1的書(shū)
        -https://api.baidu.com/books/1   # patch請(qǐng)求:局部修改主鍵為1的書(shū)
        -https://api.baidu.com/books/1   # delete請(qǐng)求:刪除主鍵為1的書(shū)
    -6、過(guò)濾。通過(guò)url上傳參的形式傳遞搜索條件
        -https://api.example.com/v1/zoos?limit=10  # 指定返回記錄的數(shù)量
        -https://api.example.com/v1/zoos?offset=10&limit=3  # 指定記錄開(kāi)始的位置
        -https://api.example.com/v1/zoos?page=2&per_page=100  # 指定第幾頁(yè),以及每頁(yè)的記錄數(shù)
        -https://api.example.com/v1/zoos?sortby=name&order=asc  # 指定返回結(jié)果按照哪個(gè)屬性排序,以及排序的順序
        -https://api.example.com/v1/zoos?animal_type_id=1  # 指定篩選條件
    -7、響應(yīng)狀態(tài)碼
        -返回?cái)?shù)據(jù)中帶狀態(tài)碼
        -{'code':100}
    -8、返回結(jié)果中帶錯(cuò)誤信息
        -{'code':100,'msg':'失敗的原因'}
    -9、服務(wù)器向用戶的返回結(jié)果,該符合一下規(guī)范
        GET/collection:返回資源對(duì)象的列表(數(shù)組)
        GET/collection/resource:返回單個(gè)資源對(duì)象(字典)
        POST/collection:返回新生成的資源對(duì)象(新增后的對(duì)象字典)
        PUT/collection/resource:返回完整的資源對(duì)象(修改后的對(duì)象字典)
        PATCH/collection/resource:返回完整的資源對(duì)象(修改后的對(duì)象字典)
        DELETE/collection/resource:返回一個(gè)空文檔
    -10、返回的數(shù)據(jù)中帶鏈接地址,連向其他API方法,使得用戶不查文檔,也知道下一步應(yīng)該做什么。
        -查詢(xún)id為1的圖書(shū)接口,返回結(jié)果示例
        {'code':100,
         'msg':'成功',
         'result':
             {'title':'金瓶梅',
              'price':12.3,
              'publish':'https://127.0.0.1/api/v1/publish/3'
             }
        }

2、APIview源碼分析

-1 APIview的as_view
    -內(nèi)部還是執(zhí)行了View的閉包函數(shù)view
    -禁用掉了csrf
    -一切皆對(duì)象,函數(shù)也是對(duì)象  函數(shù)地址.name=lqz
-2 原生View類(lèi)中過(guò)的as_view中的閉包函數(shù)view
    -本質(zhì)執(zhí)行了self.dispatch(request, *args, **kwargs),執(zhí)行的是APIView的dispatch
-3 APIView的dispatch
    def dispatch(self, request, *args, **kwargs):
        # DRF的Request類(lèi)的對(duì)象,內(nèi)部有request._request,是原生request
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request

        try:
            self.initial(request, *args, **kwargs)
            '''
            #認(rèn)證,權(quán)限,頻率
            self.perform_authentication(request)
            self.check_permissions(request)
            self.check_throttles(request)
            '''
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)

        except Exception as exc:
            # 全局的異常捕獲
            response = self.handle_exception(exc)
        # 把視圖函數(shù)(類(lèi))返回的response,又包裝了一下
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

3、Request類(lèi)分析

rest framework 傳入視圖的request對(duì)象不再是django默認(rèn)的HttpRequest對(duì)象,而是REST framework提供的擴(kuò)展了HttpRequest類(lèi)的Request類(lèi)的對(duì)象。
REST framework 提供了Parser解析器,在接收到請(qǐng)求后會(huì)自動(dòng)根據(jù)content-type指明的請(qǐng)求數(shù)據(jù)類(lèi)型(JSON,表單等)將請(qǐng)求數(shù)據(jù)進(jìn)行parser解析,解析為類(lèi)字典【QueryDict】
對(duì)象保存到Request對(duì)象中。
Request對(duì)象的數(shù)據(jù)是自動(dòng)根據(jù)前端發(fā)送的數(shù)據(jù)的格式進(jìn)行解析之后的結(jié)果。
無(wú)論前端發(fā)送哪中格式的數(shù)據(jù),我們都可以以統(tǒng)一的方式讀取數(shù)據(jù)。

-1)、Request類(lèi)
    -request._request : 原生request
    -request.data : 返回解析之后的請(qǐng)求體數(shù)據(jù), post請(qǐng)求提交的數(shù)據(jù)(urlencoded,json,formdata)request.POST里只能取urlencoded和formdata兩種格式的數(shù)據(jù)
    -request.query_params : 原生的request.GET,為了遵循restful規(guī)范,換殼更準(zhǔn)正確的名字而已。
    -request.FILES:新的
    -重寫(xiě)了__getattr__,新的request.原來(lái)私有·所有的屬性和方法,都能直接拿到
         def __getattr__(self, attr):
            return getattr(self._request, attr)

4、序列化組件介紹

-作用:
-1、序列化,序列化器會(huì)把模型對(duì)象轉(zhuǎn)換成字典,經(jīng)過(guò)response以后變成json字符串
    -Book--序列化器--》字典--通過(guò)drf:Response-->json格式字符串---》傳給前端
-2、反序列化,把客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù),經(jīng)過(guò)request以后變成字典,序列化器可以把字典轉(zhuǎn)成模型
    -json格式數(shù)據(jù)---drf:Request==》字典--序列化器---Book
-3、反序列化,完成數(shù)據(jù)校驗(yàn)功能

5 序列化組件簡(jiǎn)單使用

1 序列化的使用

-寫(xiě)一個(gè)序列化類(lèi)繼承serializers.Serializer
-在類(lèi)中寫(xiě)要序列化的字段
-在視圖類(lèi)中,實(shí)例化得到一個(gè)序列化類(lèi)的對(duì)象,把要序列化的數(shù)據(jù)傳入
    ser=BookSerializer(instance=res,many=True)
-得到字典
    ser.data就是序列化后的字典

5.1、代碼實(shí)現(xiàn)

serializer.py

from rest_framework import serializers
class BookSerializer(serializers.Serializer):
    # 要序列化哪個(gè)字段
    id=serializers.IntegerField()
    # id=serializers.CharField()
    title=serializers.CharField(max_length=32)
    price=serializers.DecimalField(max_digits=5, decimal_places=2)
    # publish=serializers.CharField(max_length=32)

models.py

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.CharField(max_length=32)

views.py

from app01 import models
from app01.serializer import BookSerializer
class Book(APIView):
    def get(self,request,*args,**kwargs):

        res=models.Book.objects.all()
        # 借助序列化器
        # 如果是多條,就是many=True
        # 如果是單個(gè)對(duì)象,就不寫(xiě)
        ser=BookSerializer(instance=res,many=True)
        # 通過(guò)序列化器得到的字典
        # ser.data
        print(ser.data)
        return Response(ser.data)

urls.py

path('books/', views.Book.as_view()),

6 序列化類(lèi)字段類(lèi)型和字段參數(shù)

字段類(lèi)型(記列的這幾個(gè))

-IntegerField
-CharField
-DecimalField
-DateTimeField
-。。。跟models中大差不差

常用字段參數(shù)

-選項(xiàng)參數(shù)
    max_length  最大長(zhǎng)度
    min_lenght  最小長(zhǎng)度
    allow_blank 是否允許為空
    trim_whitespace 是否截?cái)嗫瞻鬃址?    max_value   最小值
    min_value   最大值

-通用參數(shù)
    #重點(diǎn)
    read_only   表明該字段僅用于序列化輸出,默認(rèn)False
    write_only  表明該字段僅用于反序列化輸入,默認(rèn)False

    # 掌握
    required    表明該字段在反序列化時(shí)必須輸入,默認(rèn)True
    default     反序列化時(shí)使用的默認(rèn)值
    allow_null  表明該字段是否允許傳入None,默認(rèn)False

    # 了解
    validators  該字段使用的驗(yàn)證器
    error_messages  包含錯(cuò)誤編號(hào)與錯(cuò)誤信息的字典

7 序列化器的保存功能

如果序列化類(lèi)繼承的是Serializer,必須重寫(xiě)create方法

使用方式

-視圖類(lèi)
 def post(self, request):
    print(request.data)
    ser = BookSerializer(data=request.data)
    if ser.is_valid():
        ser.save()  # 保存到數(shù)據(jù)庫(kù)中
        return Response(ser.data)
    else:
        # 沒(méi)有校驗(yàn)通過(guò)的錯(cuò)誤信息
        return Response(ser.errors)
-序列化類(lèi)
class BookSerializer(serializers.Serializer):
    ...

    def create(self, validated_data):
        # 為什么要重寫(xiě)create?
        res=models.Book.objects.create(**validated_data)
        print(res)
        return res

8 序列化器的字段校驗(yàn)功能

三種方式

-字段自己的校驗(yàn)規(guī)則(max_length...)
-validators的校驗(yàn)
    publish = serializers.CharField(max_length=32,validators=[check,])

    def check(data):
    if len(data)>10:
        raise ValidationError('最長(zhǎng)不能超過(guò)10')
    else:
        return data
-局部和全局鉤子
    # 局部鉤子,validate_字段名,需要帶一個(gè)data,data就是該字段的數(shù)據(jù)
def validate_title(self, data):
    if data.startswith('sb'):
        raise ValidationError('不能以sb開(kāi)頭')
    else:
        return data
# 全局鉤子
def validate(self, attrs):
    title=attrs.get('title')
    publish=attrs.get('publish')
    if title==publish:
        raise ValidationError('書(shū)名不能跟出版社同名')
    else:
        return attrs

9 read_only和write_only

read_only   表明該字段僅用于序列化輸出,默認(rèn)False
write_only  表明該字段僅用于反序列化輸入,默認(rèn)False


class BookSerializer(serializers.Serializer):
    # 要序列化哪個(gè)字段
    id = serializers.IntegerField(required=False)
    # id=serializers.CharField()
    title = serializers.CharField(max_length=32,min_length=2,read_only=True)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    # 序列化的時(shí)候看不到
    publish = serializers.CharField(max_length=32,validators=[check,],write_only=True)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容