Hi,
There seems to be an issue with Django in the HttpRequest class, in
that I cannot access the data provided in a HTTP PUT request. I'm
writing a web app which uses a RESTful interface, but at the moment I
have to put together a piece of hacky middleware in order to be able
to get the PUT data.
What I'm doing now is changing the method to POST, accessing the
request.raw_post_data attribute, and then changing the method back to
PUT. This seems a little unnecessary, and I'd like to suggest the
addition of a content attribute which holds any raw content provided,
whether through POST or PUT. Not much code really needs to be changed
at all, and I'd be willing to do it myself. It's just that this seems
like a bit of a bug in Django.
> What I'm doing now is changing the method to POST, accessing the > request.raw_post_data attribute, and then changing the method back to > PUT. This seems a little unnecessary, and I'd like to suggest the > addition of a content attribute which holds any raw content provided, > whether through POST or PUT.
The raw_post_data attribute will contain the raw data regardless of the method used in the HTTP request. So it works identically for PUT and POST. Have a look at the implementation: there's nothing that restricts it to a single method. It would even work for OPTION or other HTTP verbs.
> On Wed, 2008-08-20 at 02:29 -0700, zvoase wrote:
> [...]
> > What I'm doing now is changing the method to POST, accessing the
> > request.raw_post_data attribute, and then changing the method back to
> > PUT. This seems a little unnecessary, and I'd like to suggest the
> > addition of a content attribute which holds any raw content provided,
> > whether through POST or PUT.
> The raw_post_data attribute will contain the raw data regardless of the
> method used in the HTTP request. So it works identically for PUT and
> POST. Have a look at the implementation: there's nothing that restricts
> it to a single method. It would even work for OPTION or other HTTP
> verbs.
> Regards,
> Malcolm
That may be the intended functionality, but it is not the actual
functionality (Django svn revision 9218). If the HTTP method is PUT,
then the data shows up in raw_post_data but not in the request POST
dictionary. Change the HTTP method from PUT to POST and the data
shows up in the request raw_post_data and the POST dictionary as
expected.
> On Aug 20, 6:13 am, Malcolm Tredinnick <malc...@pointy-stick.com>
> wrote:
> > On Wed, 2008-08-20 at 02:29 -0700, zvoase wrote:
> > [...]
> > > What I'm doing now is changing the method to POST, accessing the
> > > request.raw_post_data attribute, and then changing the method back to
> > > PUT. This seems a little unnecessary, and I'd like to suggest the
> > > addition of a content attribute which holds any raw content provided,
> > > whether through POST or PUT.
> > The raw_post_data attribute will contain the raw data regardless of the
> > method used in the HTTP request. So it works identically for PUT and
> > POST. Have a look at the implementation: there's nothing that restricts
> > it to a single method. It would even work for OPTION or other HTTP
> > verbs.
> > Regards,
> > Malcolm
> That may be the intended functionality, but it is not the actual
> functionality (Django svn revision 9218). If the HTTP method is PUT,
> then the data shows up in raw_post_data but not in the request POST
> dictionary. Change the HTTP method from PUT to POST and the data
> shows up in the request raw_post_data and the POST dictionary as
> expected.
On Thu, 2008-10-09 at 14:13 -0700, DaveV wrote: > Ahh - never mind - I misread the first post.
> Still, it would seem helpful if PUT data was processed in a way that > was more readily accessible, such as a PUT dictionary like the POST or > GET ones.
No, because it would be almost always wrong to do so.
The point is that request.POST is designed for web-browser POST submission, which means it's going to be data encoded as a form submission (or a mime-multipart if it contains a file upload). Web browsers are very restricted beasts. Normal web services encompass a much broader range of domains and there's no concept of a "common" format for uploads. You have to look at the content-type and act appropriately. It could be an XML document (or some subtype), image data, a word document... anything. The content is described in the HTTP method. It would be incorrect to attempt to force any of those data types into dictionaries and not particularly useful for Django to special case one particular type that will, in practice, actually be pretty uncommon (machine interacting web services tend to use more structured formats for sending data than form-encoded, since they're sending more complex data than simple forms).
If you're doing REST-based web service stuff -- as opposed to just interacting with a web browser -- you should ignore request.POST as well for the same reasons unless you have a very well-understood, restricted domain that happens to always send form-encoded data.
Apologies for being unclear in my original post, although you seem to have worked out my intention. I was trying to say that POST and PUT (and OPTIONS and DELETE) are treated identically in that all the data is in raw_post_data, not that there was an attribute for each method. The latter isn't appropriate for general cases.