From 731443b71eaa94a624952bb4ea5b142ac884cccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20B=C3=BCchler?= Date: Tue, 27 Nov 2012 10:13:15 +0100 Subject: [PATCH] Renderer negotiation: media_type specificty evaluation weak The `DefaultContentNegotiation` handler uses For example: Google Chrome sends an Accept-header of `Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`, when I request a *.png URL. After matching the media-types with the available renderers (in my case only a custom `PNGRenderer` with a `media_type='image/png'`), only `*/*;q=0.8` is left, which happens to have the same length as the "image/png" media-type defined by the renderer (9 characters). The specificity of the renderer's media-type over the Accept-header's one is only determined by length. Using your `_MediaType.precedence` would be preferable in my eyes. Regards, Fabian --- rest_framework/negotiation.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rest_framework/negotiation.py b/rest_framework/negotiation.py index dae384772..ee2800a6e 100644 --- a/rest_framework/negotiation.py +++ b/rest_framework/negotiation.py @@ -2,6 +2,7 @@ from django.http import Http404 from rest_framework import exceptions from rest_framework.settings import api_settings from rest_framework.utils.mediatypes import order_by_precedence, media_type_matches +from rest_framework.utils.mediatypes import _MediaType class BaseContentNegotiation(object): @@ -48,7 +49,8 @@ class DefaultContentNegotiation(BaseContentNegotiation): for media_type in media_type_set: if media_type_matches(renderer.media_type, media_type): # Return the most specific media type as accepted. - if len(renderer.media_type) > len(media_type): + if (_MediaType(renderer.media_type).precedence > + _MediaType(media_type).precedence): # Eg client requests '*/*' # Accepted media type is 'application/json' return renderer, renderer.media_type