[Django] #36411: get_preferred_type ignores params

12 views
Skip to first unread message

Django

unread,
May 23, 2025, 6:26:26 AMMay 23
to django-...@googlegroups.com
#36411: get_preferred_type ignores params
----------------------------+-----------------------------------------
Reporter: magicfelix | Type: Bug
Status: new | Component: HTTP handling
Version: 5.2 | Severity: Normal
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------+-----------------------------------------
I use the following code to get the preferred content type:

{{{#!python
media_types = ["text/vcard; version=4.0", "text/vcard; version=3.0",
"text/vcard", "text/directory"]
print("Preferred type:", request.get_preferred_type(media_types))
}}}

A request using the following header …
`Accept: text/vcard; version=3.0`
… produces the following result
`Preferred type: text/vcard; version=4.0`

It should instead return `text/vcard; version=3.0`, as `4.0` was not
included in the Accept header.
--
Ticket URL: <https://code.djangoproject.com/ticket/36411>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 23, 2025, 7:14:03 AMMay 23
to django-...@googlegroups.com
#36411: get_preferred_type ignores params
-------------------------------+--------------------------------------
Reporter: magicfelix | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by David Sanders):

Perhaps someone can weigh in on the correct behaviour on matching mime
types, but `MediaType.match()` only checks `<main-type>/<sub-type>`
without consideration for the `; <params>`:

{{{
def match(self, other):
if self.is_all_types:
return True
other = MediaType(other)
return self.main_type == other.main_type and self.sub_type in {
"*",
other.sub_type,
}
}}}

https://github.com/django/django/blob/d2732c30af28381f5a2ff1b08f754eeb7a6dfeca/django/http/request.py#L716-L719
--
Ticket URL: <https://code.djangoproject.com/ticket/36411#comment:1>

Django

unread,
May 23, 2025, 7:24:09 AMMay 23
to django-...@googlegroups.com
#36411: get_preferred_type ignores params
-------------------------------+--------------------------------------
Reporter: magicfelix | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by David Sanders):

There is also this old SO answer about Spring:
https://stackoverflow.com/a/32073014

> This apparently incorrect behaviour of Spring already has a Spring bug
report, SPR-10903. The Spring developers closed it as "Works as Designed",
noting:
>> I don't know any rule for comparing media types with their parameters
effectively. It really depends on the media type...If you're actually
trying to achieve REST versioning through media types, it seems that the
most common solution is to use different media types, since their format
obviously changed between versions:
--
Ticket URL: <https://code.djangoproject.com/ticket/36411#comment:2>

Django

unread,
May 23, 2025, 8:09:02 AMMay 23
to django-...@googlegroups.com
#36411: get_preferred_type ignores params
-------------------------------+--------------------------------------
Reporter: magicfelix | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Sarah Boyce):

* cc: Jake Howard (added)

--
Ticket URL: <https://code.djangoproject.com/ticket/36411#comment:3>

Django

unread,
May 23, 2025, 10:43:24 AMMay 23
to django-...@googlegroups.com
#36411: get_preferred_type ignores params
-------------------------------+--------------------------------------
Reporter: magicfelix | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by Sarah Boyce):

Looking at the Accept header in
https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2, there are
some examples including parameters:
{{{
Media ranges can be overridden by more specific media ranges or
specific media types. If more than one media range applies to a
given type, the most specific reference has precedence. For example,

Accept: text/*, text/plain, text/plain;format=flowed, */*

have the following precedence:

1. text/plain;format=flowed

2. text/plain

3. text/*

4. */*

The media type quality factor associated with a given type is
determined by finding the media range with the highest precedence
that matches the type. For example,

Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
text/html;level=2;q=0.4, */*;q=0.5

would cause the following values to be associated:

+-------------------+---------------+
| Media Type | Quality Value |
+-------------------+---------------+
| text/html;level=1 | 1 |
| text/html | 0.7 |
| text/plain | 0.3 |
| image/jpeg | 0.5 |
| text/html;level=2 | 0.4 |
| text/html;level=3 | 0.7 |
+-------------------+---------------+
}}}
So I think we probably should take into account parameters but open to
hearing other opinions
--
Ticket URL: <https://code.djangoproject.com/ticket/36411#comment:4>

Django

unread,
May 23, 2025, 11:43:35 AMMay 23
to django-...@googlegroups.com
#36411: get_preferred_type ignores params
-------------------------------+--------------------------------------
Reporter: magicfelix | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by David Sanders):

Nice find 👍 So it sounds like

- params to be included in matching, but also
- the precedence is determined by the specificity

? 🤔
--
Ticket URL: <https://code.djangoproject.com/ticket/36411#comment:5>

Django

unread,
May 27, 2025, 4:03:33 AMMay 27
to django-...@googlegroups.com
#36411: get_preferred_type ignores params
-------------------------------+--------------------------------------
Reporter: magicfelix | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by Jake Howard):

I agree with Sarah that we should take into account the parameters (I'd
not come across them before when I implemented this).

The `q` param specifically will still need some special handling when it
comes to ordering, as I think all other parameters should be considered
exact matches rather than trying to parse version numbers from them.

I believe the current implementation considers specificity in the
ordering, but I may be wrong. Either way, we should make sure it's covered
by tests!
--
Ticket URL: <https://code.djangoproject.com/ticket/36411#comment:6>

Django

unread,
May 27, 2025, 11:36:31 AMMay 27
to django-...@googlegroups.com
#36411: get_preferred_type ignores params
-------------------------------+---------------------------------------
Reporter: magicfelix | Owner: Jake Howard
Type: Bug | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+---------------------------------------
Changes (by Jake Howard):

* owner: (none) => Jake Howard
* stage: Unreviewed => Accepted
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36411#comment:7>

Django

unread,
May 27, 2025, 12:26:41 PMMay 27
to django-...@googlegroups.com
#36411: get_preferred_type ignores params
-------------------------------+---------------------------------------
Reporter: magicfelix | Owner: Jake Howard
Type: Bug | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+---------------------------------------
Changes (by Jake Howard):

* has_patch: 0 => 1

Comment:

[https://github.com/django/django/pull/19507 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/36411#comment:8>

Django

unread,
May 28, 2025, 10:58:48 AMMay 28
to django-...@googlegroups.com
#36411: get_preferred_type ignores params
---------------------------------+---------------------------------------
Reporter: magicfelix | Owner: Jake Howard
Type: Bug | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+---------------------------------------
Changes (by Natalia Bidart):

* severity: Normal => Release blocker

--
Ticket URL: <https://code.djangoproject.com/ticket/36411#comment:9>
Reply all
Reply to author
Forward
0 new messages