Opened 15 months ago
Closed 15 months ago
#34775 closed New feature (wontfix)
A case for handling aditional http methods
Reported by: | João Rodriguez | Owned by: | nobody |
---|---|---|---|
Component: | HTTP handling | Version: | 4.2 |
Severity: | Normal | Keywords: | HTTP methods, content_type |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Foreword:
I've done some research on django code and past tickets. It appears this was talked about in length more than 10 years ago. I will include some relevant links in the end but the assumed consensus was that, as stated by Carl Meyer, 12 years ago:
This special case makes sense for POST, since browsers submit HTML forms using those content types. But browsers do not PUT (and aren't likely to start), and web services are just as likely (or more likely) to use other content types (e.g. JSON, XML), so it doesn't make sense to special-case form-urlencoded for verbs that aren't used by browsers to submit forms. request.raw_post_data (an unfortunate name, since it's just the request body content, not POST-specific at all) can be accessed directly and parsed as appropriate for the application, according to the content type.
As frameworks and tools evolve, it appears to me that this discussion is worthy to be had again. As it stands, HTMX allows for a broader range of HTTP methods and is gaining traction in the Django community. They also have a standard encoding of application/x-www-form-urlencoded
with the option to enable multipart/form-data
. Which fits in very well with existing django code.
This is more of a discussion post but, for the sake of being proactive, here is a, possibly naive, proposed solution. If you are familiar with http RFC, do pitch in!
It does not make sense to me that the methods themselves are blocked when what is not supported by the standard framework are not the methods, but rather aditional encoding forms. Here is the relevant excerpt, with comments by me.
in django.http.request:354
def _load_post_and_files(self): # the initial if could be removed, as it silently discards any method for custom handling by the user # django looks perfectly capable of handling multipart and urlencoded content-types for all methods that have a body if self.method != "POST": self._post, self._files = ( QueryDict(encoding=self._encoding), MultiValueDict(), ) return if self._read_started and not hasattr(self, "_body"): self._mark_post_parse_error() return if self.content_type == "multipart/form-data": if hasattr(self, "_body"): data = BytesIO(self._body) else: data = self try: self._post, self._files = self.parse_file_upload(self.META, data) except (MultiPartParserError, TooManyFilesSent): self._mark_post_parse_error() raise elif self.content_type == "application/x-www-form-urlencoded": self._post, self._files = ( QueryDict(self.body, encoding=self._encoding), MultiValueDict(), ) # silently discards other forms of encoding for custom handling by the user else: # perhaps allow for the user to attach their own parsing interface for encoding types of their choosing? # if the encoding is unsupported by django and the interfaces, why not raise an exception? self._post, self._files = ( QueryDict(encoding=self._encoding), MultiValueDict(), )
Here are some links on past discussion on the same topic:
https://code.djangoproject.com/ticket/12635#comment:11
https://groups.google.com/g/django-users/c/BeBKj_6qNsc?hl=en
Hello João Rodriguez!
As you correctly said, this ticket would be best handled as a forum post in the Django Internals category, where you'll reach a wider audience and likely get richer feedback. The community in general is not notified about (new) tickets, but most of them are subscribed to the forum and get notifications. So in order to gain consensus, the ideal path forward is a forum post.
Also, there is/was an effort to have Configurable Content Type Parsing and Modernise Request Object by providing, among other things, custom content parsers. Would perhaps that be something you could pick up? I believe it would solve this issue and provide an amazing new feature for Django.
I'll close the ticket for now, but once that there is a community agreement for the feature request, you are welcome to come back to the ticket and point to the forum topic, so we can then re-open it. For more details, please see the documented guidelines for requesting features.
Thanks!