2015-04-04 46 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', 
}