iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
0

上一篇提到的是跟 Django ORM 結合的部分,使用上非常的便捷,這一篇來講,如果不跟 ORM 結合,以及其他的使用技巧。

不使用 ORM

如果不跟資料庫溝通,其實就可以不需要寫 serializer,單純的繼承 APIView ,並且覆寫 get 方法就可以。

# 以下摘自 REST framework 官方網站
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions
from django.contrib.auth.models import User

class ListUsers(APIView):
    """
    View to list all users in the system.

    * Requires token authentication.
    * Only admin users are able to access this view.
    """
    authentication_classes = [authentication.TokenAuthentication]
    permission_classes = [permissions.IsAdminUser]

    def get(self, request, format=None):
        """
        Return a list of all users.
        """
        usernames = [user.username for user in User.objects.all()]
        return Response(usernames)

如果是要處理 POST ,就覆寫 post() 方法即可。

Serializer

之前照著官方文件來做時,原本以為 serializer 只是將資料輸出為統一格式,事實上也不算錯,REST framework 的 serializer 的確是處理掉許多格式的問題,例如日期時間。除此之外,他也可以用來檢查資料,甚至儲存資料。

from rest_framework import serializers
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import AllowAny
from rest_framework.response import Response

class PayBillingsSerializer(serializers.Serializer):
    billingIdList = serializers.ListField(
        child=serializers.IntegerField()
    )

    class Meta:
        fields = [
            'billingIdList',
        ]

    def create(self, validated_data):
        pass

    def update(self, instance, validated_data):
        pass

class PayBillView(APIView):
    authentication_classes = (SessionAuthentication,)
    permission_classes = [AllowAny,]

    # pylint: disable=unused-argument
    def post(self, request, *args, **kwargs):
        serializer = PayBillingsSerializer(data=request.data)
        serializer.is_valid()  # 檢查

        billingIdList = serializer.data['billingIdList']
        # process
        response_data = {
        }

        return Response(response_data, status.HTTP_202_ACCEPTED)

PayBillView post() 裡,我們把 request.data 傳入 PayBillingSerializer() 建立 serializer,然後呼叫 serializer.is_valid() 來進行檢查。當傳入 API 的參數不對時,就會丟出 ValidationError 例外,並且回傳 400 Bad request 。

例外處理

最早在使用 REST framework 撰寫 API 時,會想著要自己去處理錯誤,但寫了一陣子以後,就發現,其實沒有必要,因為 REST framework 已經把這部份都處理好了。所以寫 API 時,只要丟出適當的例外,讓 REST framework 的例外處理常式去處理就可以了。如果例外處理常式不符合需求,也可以自己撰寫,並且在 REST framework settings 設定就可以了。

REST framework 的錯誤處理常式是寫在 rest_framework/views.py 裡,主要的流程就是判斷例外,然後丟出適當的 HTTP 狀態碼,並塞入錯誤訊息。客戶端在收到回應時,就可以依據 HTTP 狀態碼以及錯誤訊息來做進一步處理。

# django_ithome_ironman/exceptions.py
from rest_framework.views import exception_handler as old_exception_handler

def exception_handler(exc, context):
    old_exception_handler(exc, context)
# settings.py
REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'django_ithome_ironman.exceptions.exception_handler',
}

結語

前幾年在看 REST framework 跟 Django class based View 的原始碼時,深深覺得它們設計的很好,很多事情都只要稍稍的做一點調整,或是上 PyPI 去找搭配的套件就可以完成想做的事情。同時,也很適合用來練習閱讀原始碼。

那麼,REST framework 就介紹到這邊,想更進一步了解 REST framework 的話,可以多多閱讀網站文件以及原始碼,會很有幫助的。


上一篇
03. djangorestframework (1)
下一篇
05. drf-jwt
系列文
加速你的 Django 網站開發 - Django 的好用套件30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言