Django REST framework API 指南(20):後設資料

wcode發表於2018-03-21

官方原文連結
本系列文章 github 地址
轉載請註明出處

後設資料

REST framework 包含一個可配置的機制,用於確定 API 如何響應 OPTIONS 請求。這使你可以返回 API schema 或其他資源資訊。

對於 HTTP OPTIONS 請求應該返回哪種風格的響應,目前還沒有任何被廣泛採用的約定,所以我們提供了一種專門的風格來返回一些有用的資訊。

下面是一個示例響應,演示預設返回的資訊。

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json

{
    "name": "To Do List",
    "description": "List existing 'To Do' items, or create a new item.",
    "renders": [
        "application/json",
        "text/html"
    ],
    "parses": [
        "application/json",
        "application/x-www-form-urlencoded",
        "multipart/form-data"
    ],
    "actions": {
        "POST": {
            "note": {
                "type": "string",
                "required": false,
                "read_only": false,
                "label": "title",
                "max_length": 100
            }
        }
    }
}
複製程式碼

設定後設資料 scheme

你可以使用 'DEFAULT_METADATA_CLASS' settings key 全域性設定後設資料類:

REST_FRAMEWORK = {
    'DEFAULT_METADATA_CLASS': 'rest_framework.metadata.SimpleMetadata'
}
複製程式碼

或者你可以單獨設定一個檢視的後設資料類:

class APIRoot(APIView):
    metadata_class = APIRootMetadata

    def get(self, request, format=None):
        return Response({
            ...
        })
複製程式碼

REST framework 包只包含一個名為 SimpleMetadata 的後設資料類實現。如果你想使用另一種風格,你需要實現一個自定義的後設資料類。

建立 schema 端點

如果你對建立通過常規 GET 請求訪問的 schema 端點有特定要求,則可以考慮重新使用後設資料 API 來實現此目的。

例如,可以在檢視集上使用以下附加路由來提供可連結的 schema 端點。

@list_route(methods=['GET'])
def schema(self, request):
    meta = self.metadata_class()
    data = meta.determine_metadata(request, self)
    return Response(data)
複製程式碼

有幾個原因可以選擇採用這種方法,包括 OPTIONS 響應不能快取。


自定義後設資料類

如果你想提供一個自定義的後設資料類,你應該繼承 BaseMetadata 並且實現 determine_metadata(self, request, view) 方法。

你可能想要做的事情包括返回 schema 資訊,使用 JSON schema 等格式,或將除錯資訊返回給管理員使用者。

舉個栗子

以下類可用於限定返回到 OPTIONS 請求的資訊。

class MinimalMetadata(BaseMetadata):
    """
    Don't include field and other information for `OPTIONS` requests.
    Just return the name and description.
    """
    def determine_metadata(self, request, view):
        return {
            'name': view.get_view_name(),
            'description': view.get_view_description()
        }
複製程式碼

然後配置你的設定以使用此自定義類:

REST_FRAMEWORK = {
    'DEFAULT_METADATA_CLASS': 'myproject.apps.core.MinimalMetadata'
}
複製程式碼