極大簡(jiǎn)化Django開發(fā),讓程序員沒代碼敲的DRF框架

前置基礎(chǔ)知識(shí)

web開發(fā)的兩種模式

  • 前后端不分離
  • 前后端分離
  • 1. 前后端不分離

    極大簡(jiǎn)化Django開發(fā),讓程序員沒代碼敲的DRF框架

    完整的html頁面是在后端生成的,后端給前端返回完整的頁面,前端只是進(jìn)行展示,前端與后端的耦合度很高。

    缺點(diǎn):只適用于純網(wǎng)頁的應(yīng)用。

    優(yōu)點(diǎn):有利于網(wǎng)站的SEO優(yōu)化

    2. 前后端分離

    極大簡(jiǎn)化Django開發(fā),讓程序員沒代碼敲的DRF框架

    完整的html頁面是在前端生成的,后端只給前端返回所需的數(shù)據(jù),前端將數(shù)據(jù)填充在頁面上,前端與后端的耦合度很低。

    優(yōu)點(diǎn):可以對(duì)接不同類型的客戶端。

    缺點(diǎn):不利于SEO優(yōu)化

    3.API: 在前后端分離開發(fā)模式中,我們通常將后端開發(fā)的每個(gè)視圖都稱為一個(gè)接口或者API。

    4.RESTful設(shè)計(jì)風(fēng)格

    統(tǒng)一的接口設(shè)計(jì)方式就是普遍采用的RESTful API設(shè)計(jì)風(fēng)格

    Restful風(fēng)格設(shè)計(jì)-關(guān)鍵點(diǎn)

    • URL地址盡量使用名詞復(fù)數(shù),不要使用動(dòng)詞
    • 訪問同一個(gè)URL地址,采用不同的請(qǐng)求方式,代表要執(zhí)行不同的操作。(GET)獲取 POST(新增) PUT(修改)DELETE(刪除) 不常用:PATCH(修改) HEAD(只返回請(qǐng)求頭沒有請(qǐng)求體) OPTIONS(獲取信息)
    • 過濾參數(shù)可以放在查詢字符串。常見的參數(shù):

    ?limit=10:指定返回記錄的數(shù)量?offset=10:指定返回記錄的開始位置。?page=2&pagesize=100:指定第幾頁,以及每頁的記錄數(shù)。?sortby=name&order=asc:指定返回結(jié)果按照哪個(gè)屬性排序,以及排序順序。

    • 針對(duì)不同操作,服務(wù)器向用戶返回不同的響應(yīng)數(shù)據(jù)。一般遵循以下規(guī)范:

    1. 獲取一組數(shù)據(jù),返回一組數(shù)據(jù)2. 獲取指定數(shù)據(jù),返回指定數(shù)據(jù)3. 新增數(shù)據(jù),返回新增的數(shù)據(jù)4. 修改數(shù)據(jù),返回修改的數(shù)據(jù)5. 刪除數(shù)據(jù),返回空

    • 服務(wù)器返回的響應(yīng)數(shù)據(jù)格式,應(yīng)該盡量使用JSON
    • 響應(yīng)狀態(tài)碼,服務(wù)器向客戶端返回的狀態(tài)碼和提示信息,常見的狀態(tài)碼如下:

    200 OK - [GET/PUT]:服務(wù)器成功返回用戶請(qǐng)求的數(shù)據(jù)201 CREATED - [POST]:用戶新建數(shù)據(jù)成功。204 NO CONTENT - [DELETE]:用戶刪除數(shù)據(jù)成功。400 INVALID request - [POST/PUT]:用戶發(fā)出的請(qǐng)求有錯(cuò)誤,服務(wù)器沒有進(jìn)行新建或修改數(shù)據(jù)的操作404 NOT FOUND - [*]:用戶發(fā)出的請(qǐng)求針對(duì)的是不存在的記錄,服務(wù)器沒有進(jìn)行操作,該操作是冪等的。。500 INTERNAL SERVER ERROR - [*]:服務(wù)器發(fā)生錯(cuò)誤,用戶將無法判斷發(fā)出的請(qǐng)求是否成功。

    了解:

    1. 域名:使用專有域名
    2. 版本:將版本信息放在url地址
    3. 錯(cuò)誤:將錯(cuò)誤信息返回
    4. 在訪問api接口時(shí),將和接口相關(guān)的其他API接口的地址也在響應(yīng)數(shù)據(jù)中返回

    使用Django開發(fā)REST API

    需求: 設(shè)計(jì)一套符合RestAPI風(fēng)格的接口,提供以下5個(gè)接口: 1. 獲取所有直播間數(shù)據(jù):GET /lives/ 2. 新增一本直播間數(shù)據(jù):POST /lives/ 3. 獲取指定的直播間數(shù)據(jù)(根據(jù)id):GET /lives/(?P<pk>d )/ 4. 修改指定的直播間數(shù)據(jù)(根據(jù)id):PUT /lives/(?P<pk>d )/ 5. 刪除指定的直播間數(shù)據(jù)(根據(jù)id):DELETE /lives/(?P<pk>d )/

    模型類定義

    # models.pyclass LiveInfo(models.Model): live_id = models.IntegerField(verbose_name='直播間號(hào)') live_streamer = models.CharField(max_length=20, verbose_name='主播名字') live_title = models.CharField(max_length=30, verbose_name='直播間標(biāo)題') live_pop = models.IntegerField(default=0, verbose_name='人氣') live_content = models.CharField(default='未設(shè)定', max_length=20, verbose_name='直播類型') is_delete = models.BooleanField(default=False, verbose_name='刪除標(biāo)記') class Meta: db_table = 'tb_lives' verbose_name = '直播間' verbose_name_plural = verbose_name def __str__(self): return self.live_streamer

    views.py文件中定義視圖實(shí)現(xiàn)API接口:

    class LiveListView(View): def get(self, request): """獲取所有直播間""" lives = LiveInfo.objects.all() lives_list = [] for live in lives: lives_list.append({ 'live_id': live.live_id, 'live_streamer': live.live_streamer, 'live_title': live.live_title, 'live_pop': live.live_pop, 'live_content': live.live_content }) return JsonResponse(lives_list, safe=False) def post(self, request): """新增直播間""" passclass LiveDetailView(View): def get(self, request, pk): """查詢一間直播間信息""" pass def put(self, request, pk): """修改直播間信息""" pass def delete(self, request, pk): """刪除直播間""" pass

    RestAPI開發(fā)核心工作

    分析上節(jié)直播間管理的5個(gè)API接口,可以發(fā)現(xiàn),在開發(fā)REST API接口時(shí),視圖中做的最主要有三件事:

    • 將請(qǐng)求的數(shù)據(jù)(如JSON格式)轉(zhuǎn)換為模型類對(duì)象
    • 操作數(shù)據(jù)庫(kù)
    • 將模型類對(duì)象轉(zhuǎn)換為響應(yīng)的數(shù)據(jù)(如JSON格式)

    在以上操作中,涉及到兩個(gè)概念:序列化和反序列化。

    序列化Serialization

    將程序中的一個(gè)數(shù)據(jù)結(jié)構(gòu)類型轉(zhuǎn)換為其他格式(字典、JSON、XML等),例如將Django中的模型類對(duì)象轉(zhuǎn)換為字典或JSON字符串,這個(gè)轉(zhuǎn)換過程我們稱為序列化。

    反序列化

    將其他格式(字典、JSON、XML等)轉(zhuǎn)換為程序中的數(shù)據(jù),例如將JSON字符串或字典轉(zhuǎn)換保存為Django中的模型類對(duì)象,這個(gè)過程我們稱為反序列化。

    在開發(fā)REST API接口時(shí),我們?cè)?strong>視圖中在做的最核心的事是:

    • 將數(shù)據(jù)庫(kù)數(shù)據(jù)序列化為前端所需要的格式,并返回。
    • 將前端發(fā)送的數(shù)據(jù)反序列化保存到模型類對(duì)象,并保存到數(shù)據(jù)庫(kù)中。

    Django REST framework 簡(jiǎn)介

    Django REST framework 框架是一個(gè)用于構(gòu)建Web API 的強(qiáng)大而又靈活的工具。通常簡(jiǎn)稱為DRF框架 或 REST framework。

    作用:幫助我們大大提高REST API的開發(fā)速度

    核心功能:

    • 序列化器:序列化和反序列化
    • 類視圖,MiXin擴(kuò)展類:簡(jiǎn)化視圖代碼的編寫

    環(huán)境安裝與使用:

    pip install djangorestframework# 注:DRF框架依賴于Django,需要先安裝Django環(huán)境,再安裝djangorestframework。

    在Django項(xiàng)目中使用DRF框架進(jìn)行開發(fā)時(shí),需要將rest_framework在INSTALLED_APPS中進(jìn)行注冊(cè):

    INSTALLED_APPS = [ ... 'rest_framework',]

    序列化器

    序列化器類定義

    from rest_framework import serializersclass LiveInfoSerializer(serializers.Serializer): id = serializers.IntegerField(label='ID', read_only=True) live_id = serializers.IntegerField(label='直播間號(hào)') live_streamer = serializers.CharField(max_length=20, label='主播名字', required=False) live_title = serializers.CharField(max_length=30, label='直播間標(biāo)題') live_pop = serializers.IntegerField(default=0, label='人氣', required=False) live_content = serializers.CharField(default='未設(shè)定', max_length=20, label='直播類型', required=False) is_delete = serializers.BooleanField(default=False, label='刪除標(biāo)記', required=False)

    選項(xiàng)參數(shù):

    • write_only:為True,字段只在反序列化時(shí)使用
    • read_only:為True,字段只在序列化時(shí)使用
    • required:為True,如果字段在反序列化時(shí)使用,該字段必傳傳入
    • default:設(shè)置序列化和反序列化操作時(shí)的默認(rèn)值
    • max_length和min_length:設(shè)置字符串的最大長(zhǎng)度和最小長(zhǎng)度
    • max_value和min_value:設(shè)置數(shù)字的最大值和最小值

    序列化操作

    • 序列化單個(gè)對(duì)象:序列化單個(gè)對(duì)象obj時(shí),在創(chuàng)建序列化器對(duì)象時(shí),將obj傳遞給instance即可

    from livetest.models import LiveInfofrom livetest.serializers import LiveInfoSerializerclass LiveDetailView(View): def get(self, request, pk): """查詢一間直播間信息""" try: live = LiveInfo.objects.get(pk=pk) except LiveInfo.DoesNotExist: return HttpResponse(status=404) # 創(chuàng)建序列化器對(duì)象 serializer = LiveInfoSerializer(live) # 返回序列化之后的數(shù)據(jù) return JsonResponse(serializer.data)

    • 序列化多個(gè)對(duì)象:如果要被序列化的是包含多個(gè)對(duì)象的查詢集QuerySet或list,在創(chuàng)建序列化器對(duì)象時(shí),需要添加many=True參數(shù)

    class LiveListView(View): def get(self, request): """獲取所有直播間""" lives = LiveInfo.objects.all() # 創(chuàng)建序列化器對(duì)象 serialize# 獲取序列化之后的數(shù)據(jù)r = LiveInfoSerializer(lives, many=True) return JsonResponse(serializer.data, safe=False)

    • 關(guān)聯(lián)對(duì)象嵌套序列化

    如果在序列化對(duì)象數(shù)據(jù)時(shí),需要將其關(guān)聯(lián)的對(duì)象一并序列化,則定義序列化器類的字段時(shí),需要在定義對(duì)應(yīng)的關(guān)聯(lián)對(duì)象嵌套序列化字段,比如和直播分類關(guān)聯(lián)的直播間。對(duì)于嵌套關(guān)聯(lián)字段,可以采用以下3種方式進(jìn)行定義:

    1.PrimaryKeyRelatedField :將關(guān)聯(lián)對(duì)象序列化為關(guān)聯(lián)對(duì)象的主鍵。

    # 在LiveInfoSerializer中添加此字段Ltype = serializers.PrimaryKeyRelatedField(label='直播類型', read_only=True)或Ltype = serializers.PrimaryKeyRelatedField(label='直播類型', queryset=LiveInfo.objects.all())

    2.使用關(guān)聯(lián)對(duì)象的序列化器

    Ltype = LiveInfoSerializer()

    3.StringRelatedField:將關(guān)聯(lián)對(duì)象序列化為關(guān)聯(lián)對(duì)象模型類__str__方法的返回值。

    Ltype = serializers.StringRelatedField(label='直播類型')

    如果和一個(gè)對(duì)象關(guān)聯(lián)的對(duì)象有多個(gè),在序列化器類中定義嵌套序列化字段時(shí),需要多添加一個(gè)many=True參數(shù)。

    反序列化操作

    # 1. 創(chuàng)建序列化器對(duì)象serializer = 序列化器類(data=<待校驗(yàn)字典數(shù)據(jù)>)# 2. 數(shù)據(jù)校驗(yàn):成功返回True,失敗返回Falseserializer.is_valid()# 3. 獲取校驗(yàn)成功之后的數(shù)據(jù)serializer.validated_data# 4. 如果校驗(yàn)失敗,獲取失敗的錯(cuò)誤提示信息serializer.errors

    調(diào)用is_valid時(shí),會(huì)根據(jù)對(duì)應(yīng)序列化類字段是否需要傳遞、字段類型以及一些選項(xiàng)參數(shù)對(duì)data中的數(shù)據(jù)進(jìn)行校驗(yàn)。

    在調(diào)用is_valid進(jìn)行數(shù)據(jù)校驗(yàn)時(shí),除了一些基本的默認(rèn)驗(yàn)證行為,可能還需要補(bǔ)充一些驗(yàn)證行為,可以使用以下三種方法:

  • 針對(duì)指定字段添加validators選項(xiàng)參數(shù)添加補(bǔ)充驗(yàn)證函數(shù)
  • 在序列化器類中定義特定方法validate_<field_name>針對(duì)特定字段進(jìn)行補(bǔ)充驗(yàn)證
  • 在序列化器類中定義方法validate進(jìn)行補(bǔ)充驗(yàn)證
  • 數(shù)據(jù)校驗(yàn)通過之后,可以調(diào)用序列化對(duì)象的save方法進(jìn)行數(shù)據(jù)保存,save方法內(nèi)部會(huì)調(diào)用對(duì)應(yīng)序列化器類中的create或update方法,可以在create中實(shí)現(xiàn)數(shù)據(jù)新增,在update中實(shí)現(xiàn)數(shù)據(jù)更新。

    ModelSerializer使用

    如果序列化器類對(duì)應(yīng)的是Django的某個(gè)模型類,則定義序列化器類時(shí),可以直接繼承于ModelSerializer。

    ModelSerializer是Serializer類的子類,相對(duì)于Serializer,提供了以下功能:

    • 基于模型類字段自動(dòng)生成序列化器類的字段
    • 包含默認(rèn)的create()和update()方法的實(shí)現(xiàn)

    class LiveInfoSerializer(serializers.ModelSerializer): class Meta: model = LiveInfo # 使用fields來指明依據(jù)模型類的哪些字段生成序列化器類的字段,__all__表明包含所有字段,也可以指明具體哪些字段 # fields = '__all__' # fields = ('id', 'title', ...) # 使用exclude可以指明排除哪些字段 exclude = ['is_delete'] extra_kwargs = { # 'live_title': {'validators': [live_name]}, 'live_streamer': {'required': False}, 'live_pop': {'min_value': 0, 'required': False}, }

    案例-序列化器改寫后的視圖代碼:

    import jsonfrom django.http import JsonResponse, HttpResponsefrom django.views import Viewfrom livetest.models import LiveInfofrom livetest.serializers import LiveInfoSerializerclass LiveListView(View): def get(self, request): """獲取所有直播間""" lives = LiveInfo.objects.all() serializer = LiveInfoSerializer(lives, many=True) return JsonResponse(serializer.data, safe=False) def post(self, request): """新增直播間""" json_dict = json.dumps(request.body.decode()) serializer = LiveInfoSerializer(data=json_dict) serializer.is_valid(raise_exception=True) serializer.save() # 返回新增直播間 return JsonResponse(serializer.data, status=201)class LiveDetailView(View): def get(self, request, pk): """查詢一間直播間信息""" try: live = LiveInfo.objects.get(pk=pk) except LiveInfo.DoesNotExist: return HttpResponse(status=404) serializer = LiveInfoSerializer(live) return JsonResponse(serializer.data) def put(self, request, pk): """修改直播間信息""" try: live = LiveInfo.objects.get(pk=pk) except LiveInfo.DoesNotExist: return HttpResponse(status=404) json_dict = json.dumps(request.body.decode()) serializer = LiveInfoSerializer(live, data=json_dict) serializer.is_valid(raise_exception=True) serializer.save() return JsonResponse(serializer.data) def delete(self, request, pk): """刪除直播間""" try: live = LiveInfo.objects.get(pk=pk) except LiveInfo.DoesNotExist: return HttpResponse(status=404) # 參數(shù)校驗(yàn) live.delete() return HttpResponse(status=204)

    視圖部分

    APIView

    APIView是REST framework提供的所有視圖的基類,繼承自Django的View類。

    APIView和View的區(qū)別:

    • 請(qǐng)求對(duì)象:Request類的對(duì)象request.data:解析之后的請(qǐng)求體數(shù)據(jù) ,request.query_params:解析之后的查詢字符串?dāng)?shù)據(jù)
    • 響應(yīng)對(duì)象:Response類對(duì)象統(tǒng)一返回Response對(duì)象,原始響應(yīng)數(shù)據(jù)根據(jù)客戶端請(qǐng)求頭Accept轉(zhuǎn)換為對(duì)應(yīng)的格式進(jìn)行返回
    • 異常處理機(jī)制默認(rèn)異常處理機(jī)制,會(huì)將視圖中出現(xiàn)的異常處理成合適的響應(yīng)返回給客戶端
    • 其他:認(rèn)證&權(quán)限&限流

    案例-使用APIView改寫RestAPI:

    GenericAPIView

    繼承自APIView,在APIView功能基礎(chǔ)上,主要增加了操作序列化器和數(shù)據(jù)庫(kù)查詢的屬性和方法。

    GenericAPIView和APIView的區(qū)別:

    • 繼承自APIView
    • 封裝了操作序列化器的屬性和方法屬性:serializer_class方法:get_serializer_class和get_serializer
    • 封裝了數(shù)據(jù)庫(kù)操作的屬性和方法屬性:queryset方法:get_queryset和get_object
    • 其他:過濾和分頁

    案例-使用GenericAPIView改寫RestAPI:

    from rest_framework import statusfrom rest_framework.generics import GenericAPIViewfrom rest_framework.response import Responsefrom livetest.models import LiveInfofrom livetest.serializers import LiveInfoSerializerclass LiveListView(GenericAPIView): serializer_class = LiveInfoSerializer queryset = LiveInfo.objects.all() def get(self, request): """獲取所有直播間""" queryset = self.get_queryset() serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) def post(self, request): """新增直播間""" serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() # 返回新增直播間 return Response(serializer.data, status=status.HTTP_201_CREATED)class LiveDetailView(GenericAPIView): serializer_class = LiveInfoSerializer queryset = LiveInfo.objects.all() def get(self, request, pk): """查詢一間直播間信息""" instance = self.get_object() serializer = self.get_serializer(instance) return Response(serializer.data) def put(self, request, pk): """修改直播間信息""" instance = self.get_object() serializer = self.get_serializer(instance, data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data) def delete(self, request, pk): """刪除直播間""" instance = self.get_object() # 參數(shù)校驗(yàn) instance.delete() return Response(status=status.HTTP_204_NO_CONTENT)

    Mixin擴(kuò)展類

    使用GenericAPIView改寫之后的RestAPI接口中,圖書管理的各個(gè)代碼已經(jīng)變成了通用的代碼,這些代碼和視圖所使用的序列化器類和查詢集已經(jīng)沒有直接的關(guān)系,DRF框架已經(jīng)將這些代碼做了封裝,就是5個(gè)Mixin擴(kuò)展類。

    極大簡(jiǎn)化Django開發(fā),讓程序員沒代碼敲的DRF框架

    案例-Mixin改寫RestAPI接口:

    from rest_framework import mixinsfrom rest_framework.generics import GenericAPIViewfrom livetest.models import LiveInfofrom livetest.serializers import LiveInfoSerializerclass LiveListView(mixins.ListModelMixin, mixins.CreateModelMixin,GenericAPIView): serializer_class = LiveInfoSerializer queryset = LiveInfo.objects.all() def get(self, request): """獲取所有直播間""" return self.list(request) def post(self, request): """新增直播間""" return self.create(request)class LiveDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, GenericAPIView): serializer_class = LiveInfoSerializer queryset = LiveInfo.objects.all() def get(self, request, pk): """查詢一間直播間信息""" return self.retrieve(request, pk) def put(self, request, pk): """修改直播間信息""" return self.update(request, pk) def delete(self, request, pk): """刪除直播間""" return self.destroy(request, pk)

    子類視圖:Django框架為了方便視圖的編寫,還提供了9個(gè)子類視圖類。

    子類視圖一定同時(shí)繼承了GenericAPIView和對(duì)應(yīng)的Mixin擴(kuò)展類,同時(shí)類中提供了對(duì)應(yīng)的請(qǐng)求處理方法,并且請(qǐng)求處理方法中調(diào)用的就是Mixin擴(kuò)展類中封裝的通用方法。

    極大簡(jiǎn)化Django開發(fā),讓程序員沒代碼敲的DRF框架

    案例-子類視圖改寫RestAPI接口:

    from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIViewfrom livetest.models import LiveInfofrom livetest.serializers import LiveInfoSerializerclass LiveListView(ListCreateAPIView): serializer_class = LiveInfoSerializer queryset = LiveInfo.objects.all()class LiveDetailView(RetrieveUpdateDestroyAPIView): serializer_class = LiveInfoSerializer queryset = LiveInfo.objects.all()

    視圖集ViewSet

    將操作同一組資源相關(guān)的處理方法放在同一個(gè)類中,這個(gè)類叫做視圖集。

    基本使用:

  • 繼承視圖集父類ViewSet
  • 視圖集中的處理方法不再以請(qǐng)求方法(get等)命名,而是以對(duì)應(yīng)的action操作命名
  • url地址配置時(shí)需要明確指明請(qǐng)求方式和處理函數(shù)之間的對(duì)應(yīng)關(guān)系
  • 常用視圖集父類:

    • ViewSet:繼承自APIView與ViewSetMixin,作用也與APIView基本類似,提供了身份認(rèn)證、權(quán)限校驗(yàn)、流量管理等。
    • GenericViewSet:繼承自GenericAPIView與ViewSetMixin,可以直接搭配Mixin擴(kuò)展類使用。
    • ModelViewSet:繼承自GenericViewSet和5個(gè)Mixin擴(kuò)展類。
    • ReadOnlyModelViewSet:繼承自GenericViewSet,同時(shí)包括了ListModelMixin、RetrieveModelMixin。

    案例-ViewSet改寫:

    from django.http import Http404from rest_framework import statusfrom rest_framework.response import Responsefrom rest_framework.viewsets import ViewSetfrom livetest.models import LiveInfofrom livetest.serializers import LiveInfoSerializerclass LiveInfoViewSet(ViewSet): def list(self, request): """獲取所有直播間""" lives = LiveInfo.objects.all() serializer = LiveInfoSerializer(lives, many=True) return Response(serializer.data) def create(self, request): """新增直播間""" serializer = LiveInfoSerializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() # 返回新增直播間 return Response(serializer.data, status=status.HTTP_201_CREATED) def retrieve(self, request, pk): """查詢一間直播間信息""" try: live = LiveInfo.objects.get(pk=pk) except LiveInfo.DoesNotExist: raise Http404 serializer = LiveInfoSerializer(live) return Response(serializer.data) def update(self, request, pk): """修改直播間信息""" try: live = LiveInfo.objects.get(pk=pk) except LiveInfo.DoesNotExist: raise Http404 serializer = LiveInfoSerializer(live, data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data) def destroy(self, request, pk): """刪除直播間""" try: live = LiveInfo.objects.get(pk=pk) except LiveInfo.DoesNotExist: raise Http404 # 參數(shù)校驗(yàn) live.delete() return Response(status=status.HTTP_204_NO_CONTENT)# urls.pyfrom django.conf.urls import urlfrom booktest import viewsurlpatterns = [ url(r'^lives/$', views.LiveInfoViewSet.as_view({ 'get': 'list', 'post': 'create' })), url(r'^lives/(?P<pk>d )/$', views.LiveInfoViewSet.as_view({ 'get': 'retrieve', 'put': 'update', 'delete': 'destroy' }))]

    案例-GenericViewSet改寫:

    案例-ModelViewSet并添加了一些額外的方法改寫:

    from rest_framework.decorators import actionfrom rest_framework.response import Responsefrom rest_framework.viewsets import ModelViewSetfrom livetest.models import LiveInfofrom livetest.serializers import LiveInfoSerializerclass LiveInfoView(ModelViewSet): serializer_class = LiveInfoSerializer queryset = LiveInfo.objects.all() lookup_value_regex = 'd ' @action(methods='get', detail=False) def latest(self, request): """查詢最新的直播間""" live = LiveInfo.objects.latest('pk') serializer = self.get_serializer(live) return Response(serializer.data) @action(methods='put', detail=True) def change_pop(self, request, pk): """修改指定直播間的人氣""" live = self.get_object() live.bread = request.data.get('live_pop') live.save() serializer = self.get_serializer(live) return Response(serializer.data)# urls.pyfrom django.conf.urls import urlfrom . import viewsurlpatterns = [ url(r'^lives/$', views.LiveInfoViewSet.as_view({ 'get': 'list', 'post': 'create' })), url(r'^lives/(?P<pk>d )/$', views.LiveInfoViewSet.as_view({ 'get': 'retrieve', 'put': 'update', 'delete': 'destroy' })), url(r'^lives/latest/$', views.LiveInfoViewSet.as_view({ 'get': 'latest' })), url(r'^lives/(?P<pk>d )/change_pop/$', views.LiveInfoViewSet.as_view({ 'put': 'change_pop' }))]

    路由Router:動(dòng)態(tài)生成視圖集中處理方法的url配置項(xiàng)。

    對(duì)于視圖集ViewSet,除了可以自己手動(dòng)進(jìn)行URL配置指明請(qǐng)求方式與action處理函數(shù)之間的對(duì)應(yīng)關(guān)系外,還可以使用路由Router來自動(dòng)生成路由信息。

    REST framework提供了兩個(gè)Router類:

    • SimpleRouter
    • DefaultRouter

    案例-router改寫:

    # urls.pyfrom rest_framework.routers import DefaultRouterfrom livetest import viewsurlpatterns = []# 創(chuàng)建Router對(duì)象router = DefaultRouter()# 注冊(cè)routerrouter.register('lives', views.LiveInfoView, base_name='live')# 添加配置項(xiàng)urlpatterns = router.urls

  • lookup_value_regex: 設(shè)置router生成路由時(shí),從url中提取pk參數(shù)對(duì)應(yīng)的正則表達(dá)式
  • 視圖集中額外處理方法的配置項(xiàng),需要添加action裝飾器
  • DefaultRouter和SimpleRouter的區(qū)別多生成一個(gè)根路徑(/)配置項(xiàng),并且每個(gè)配置項(xiàng)地址后都可以跟上.json,直接返回json數(shù)據(jù)。
  • DRF框架到此常用的功能都已經(jīng)講解完畢了,當(dāng)然DRF框架還有其他功能:認(rèn)證、權(quán)限、限流、過濾、排序、分頁和異常處理機(jī)制。將在后面講述,敬請(qǐng)關(guān)注。

    作者簡(jiǎn)介:Python菜鳥工程師,將在接下來的一段時(shí)間內(nèi)與大家分享一些與Python相關(guān)的知識(shí)點(diǎn)。如若文中出現(xiàn)問題,各位大佬多多指點(diǎn),互相學(xué)習(xí)。喜歡的關(guān)注一個(gè)吧!謝謝!

    相關(guān)新聞

    聯(lián)系我們
    聯(lián)系我們
    公眾號(hào)
    公眾號(hào)
    在線咨詢
    分享本頁
    返回頂部