summaryrefslogtreecommitdiff
path: root/django/http/request.py
diff options
context:
space:
mode:
Diffstat (limited to 'django/http/request.py')
-rw-r--r--django/http/request.py19
1 files changed, 15 insertions, 4 deletions
diff --git a/django/http/request.py b/django/http/request.py
index c26a4954d1..daaf3748cc 100644
--- a/django/http/request.py
+++ b/django/http/request.py
@@ -90,7 +90,7 @@ class HttpRequest:
@cached_property
def accepted_types(self):
- """Return a list of MediaType instances, in order of preference."""
+ """Return a list of MediaType instances, in order of preference (quality)."""
header_value = self.headers.get("Accept", "*/*")
return sorted(
(
@@ -98,19 +98,30 @@ class HttpRequest:
for token in header_value.split(",")
if token.strip() and (media_type := MediaType(token)).quality != 0
),
+ key=operator.attrgetter("quality", "specificity"),
+ reverse=True,
+ )
+
+ @cached_property
+ def accepted_types_by_precedence(self):
+ """
+ Return a list of MediaType instances, in order of precedence (specificity).
+ """
+ return sorted(
+ self.accepted_types,
key=operator.attrgetter("specificity", "quality"),
reverse=True,
)
def accepted_type(self, media_type):
"""
- Return the preferred MediaType instance which matches the given media type.
+ Return the MediaType instance which best matches the given media type.
"""
media_type = MediaType(media_type)
return next(
(
accepted_type
- for accepted_type in self.accepted_types
+ for accepted_type in self.accepted_types_by_precedence
if media_type.match(accepted_type)
),
None,
@@ -130,7 +141,7 @@ class HttpRequest:
if not desired_types:
return None
- # Of the desired media types, select the one which is most desirable.
+ # Of the desired media types, select the one which is preferred.
return min(desired_types, key=lambda t: self.accepted_types.index(t[0]))[1]
def accepts(self, media_type):