2016-05-16 57 views
4

我正在創建一個需要所有JSON響應的自定義結構的API。如何在Django Rest Framework中創建自定義JSON有效內容結構?

{ 
    code: 200, 
    payload: [ 
     {...}, 
     {...}, 
     {...} 
    ] 
} 

其中​​包含查詢返回的所有項目。

我創建了一個自定義Renderer,它擴展了JSONRenderer,但是爲了訪問我需要訪問render_context的響應代碼。

class VendorRenderer(JSONRenderer): 
    def render(self, data, accepted_media_type=None, render_context=None): 
     response = render_context['response'] 
     data = { 
      'code': response.status_code, 
      'payload': data 
     } 
     return super(VendorRenderer, self).render(data, accepted_media_type, render_context) 

這是可以做這種包裝的還是它應該發生在其他地方,如視圖集或延長Response對象正確的地方?

回答

4

這是包裝響應的正確位置,因爲響應是在中間件中執行錯誤檢查後呈現的。

在視圖中執行此操作可能會導致意外的結果,例如,參數code無法正確捕獲序列化錯誤,並將其封裝在自定義序列化程序中將無法訪問響應對象。另外,您可能希望在響應中包含身份驗證或限制錯誤。

要知道,這種情況發生的任何分頁也將被包裹在你的​​參數:

{ 
    "code":200, 
    "payload": { 
     "count": 20, 
     "next": 2, 
     "previous": 0, 
     "results": [ 
      ... 
     ] 
    } 
} 

一種解決方法是使用HTTP標頭以實現分頁。

from rest_framework.pagination import PageNumberPagination 
from rest_framework.response import Response 

class StandardResultsSetHeaderPagination(PageNumberPagination): 
    page_size = 10 
    page_size_query_param = 'page_size' 
    max_page_size = 1000 

    def get_paginated_response(self, data): 
     headers = { 
      'X-Count': self.page.paginator.count, 
      'X-Next':  self.get_next_link(), 
      'X-Previous': self.get_previous_link() 
     } 
     return Response(data, headers=headers) 
+1

分頁有點令人沮喪,但我想我可以弄清楚如何將結構提取到結構中,因爲無論如何我們都在爲這種事情考慮一個「meta」字段。 – Soviut

+0

我同意你的意見。我面臨類似的問題,並將分頁重定位到請求的標題。這是我的實施:https://dpaste.de/6swb –

+1

謝謝,我已經添加您的片段的答案。 – Soviut

相關問題