2015-04-04 77 views
4

我想構建一個默認輸出JSON的Django-rest-framework REST API,但也有XML可用。Django-rest-framework:設置默認渲染器不工作?

我看了Renderers chapter of the documentation section on default ordering,並把這個在我的設置文件:

REST_FRAMEWORK = { 
    'DEFAULT_RENDERER_CLASSES': (
     'rest_framework.renderers.JSONRenderer', 
     'rest_framework_xml.renderers.XMLRenderer', 
    ) 
} 

然而,這種默認輸出XML。切換順序沒有區別。

如果我將format=json附加到URL,並且我完全刪除了XMLRenderer行,我確實會得到JSON。

如何將JSON設置爲默認值?

我使用Django的v1.7和Django-rest-framework的v3.1.1。

更新:由於這裏要求是我的看法代碼:

class CountyViewSet(viewsets.ModelViewSet): 
    queryset = County.objects.all() 
    serializer_class = CountySerializer 

和串行:

router = routers.DefaultRouter() 
router.register(r'county', CountyViewSet) 
urlpatterns = [ 
    url(r'^', include(router.urls)), 
] 
+0

到的settings.py任何解決這個問題?我面臨同一個問題。 – 2018-01-29 16:53:10

回答

0

可以:

from rest_framework import serializers 
class CountySerializer(serializers.ModelSerializer): 
    class Meta: 
     model = County 
     fields = ('id', 'name', 'name_slug', 'ordering') 
從我的網址文件

然後終於你發佈你的代碼的實際意見?

您是否在您的意見中定義了renderer_classes?因爲這會覆蓋默認設置。

class YourView(APIView): 
    renderer_classes = (XMLRenderer, JSONRenderer,) 
+0

謝謝你。我已經更新了這個問題。不,我沒有在我的視圖中定義'renderer_classes'。 – Richard 2015-04-05 09:30:30

+0

如果我嘗試在單個視圖中設置'renderer_classes',如上所述,那麼XML仍然是默認設置,不管我將這些類放入哪個順序。也許這是因爲XML渲染器實際上是第三方模塊('djangorestframework_xml' ),它不想和默認值一起玩。 – Richard 2015-04-05 09:34:33

0

最有可能你打,特別是如果你使用瀏覽器測試的問題是,XML在Accepts頭自帶JSON之前。正因爲如此,Django REST框架正在渲染XML,因爲您特別要求它,即使它不是您所期望的。

通過向DRF提供默認渲染器列表,您告訴它「如果我不告訴您在我的視圖中使用其他渲染器,請使用這些列表」。然後,DRF會將這些媒體類型與您的Accepts標題中的媒體類型進行比較,以確定在響應中使用的最佳呈現器。訂單沒有關係,除非您在Accepts標題中沒有包含特定的媒體類型,此時它應該默認爲列表中的第一個。

+0

謝謝。問題是我無法強迫我的用戶(可能使用任何瀏覽器)以某種方式設置他們的「接受」標題。那麼默認情況下返回JSON基本上是不可能的,但是也可以使用DRF來提供XML? – Richard 2015-04-05 21:58:40

+0

當'application/xml'處於Accepts頭部時,默認情況下強制DRF不能返回XML,_不會強制XML在不同的媒體類型下返回。這會對實際需要使用API​​的任何XML客戶端產生不利影響,這不是一個好主意。 – 2015-04-05 22:34:36

+0

如果DRF遵守我的設置中指定的順序,而不是在客戶端的「接受」標題中指定的順序,那將會更好。如果需要的話,客戶端總是可以使用'format = xml'專門請求XML。 – Richard 2015-04-06 20:28:57

0

我的解決方案:文件renderers.py

from rest_framework.negotiation import DefaultContentNegotiation 

class IgnoreClientContentNegotiation(DefaultContentNegotiation): 

    logger = logging.getLogger(__name__) 
    def select_renderer(self, request, renderers, format_suffix): 
     """ 
     Select the first renderer in the `.renderer_classes` list. 
     """ 
     # Allow URL style format override. eg. "?format=json 
     format_query_param = self.settings.URL_FORMAT_OVERRIDE 
     format = format_suffix or request.query_params.get(format_query_param) 
     request.query_params.get(format_query_param), format)) 

     if format is None: 
      return (renderers[0], renderers[0].media_type) 
     else: 
      return DefaultContentNegotiation.select_renderer(self, request, renderers, format_suffix) 

現在剛需加入

REST_FRAMEWORK = { 
(...) 
'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'myapp.renderers.IgnoreClientContentNegotiation', 
}