Re: Support POST of application/json content type

2013-09-04 Thread Curtis Maloney
To weight in from an author of a different API tool

In django-nap there's a simple "get_request_data" method which,
essentially, determines how to parse the request according to the content
type.  However, currently each API only supports a single serialiser format
[and HTTP Form encoding] so there's little guessing involved.

However, I wouldn't want to see the same on Request, unless there was also
a direct way to imply the type you want.  For instance, if I get a request
that's in XML, and I ask for request.JSON, I'd like it to either yield
empty or raise an error.  Whereas when I didn't case, accessing
request.DATA would make a best guess.

So I see two paths... either you use a "Decode it for me according to
content-type" interface, or a "Treat is as this type, and fail predictably
if it's not" one.

The current GET/POST is, of course, the latter.  And there's no reason we
can't have both :)

--
Curtis



On 5 September 2013 04:06, Jonathan Slenders wrote:

> Would that mean that the object returned by request.DATA/POST/whatever
> could be a different type, depending on what the user posted?
>
> I don't want to see code like:
>
> if isinstance(request.DATA, YamlObject): ...
> elif isinstance(request.DATA, dict): ...
>
> although, I'm not sure how any view could handle any random content-type...
>
>
>
> Le mercredi 4 septembre 2013 13:57:29 UTC+2, Marc Tamlyn a écrit :
>>
>> The thing with request.POST is that it's kinda unintuitive when extended
>> to other HTTP methods (e.g. PUT). This is why the old request.raw_post_data
>> was renamed request.body.
>>
>> request.POST would behave in the expected traditional web way of picking
>> up form encoded POST data, which would also be available in request.DATA as
>> well, but request.DATA is the "new" way of doing it. Personally, I'd
>> lowercase it though, to remove confusion with the PHP $POST $GET $REQUEST
>> which we mimic on the request object. The generally have different use
>> cases anyway - one for complex web things and the other for standard web
>> browsers.
>>
>> (the above is what tom said...)
>>
>> Tom - what else do you have in DRF's Request that you would need?
>>
>>
>> On 4 September 2013 12:56, Tom Christie  wrote:
>>
>>> > Creating a request.DATA attribute would break compatibility with old
>>> code and seem to me less intuitive.
>>>
>>> The implementation would ensure `request.POST` would still be populated
>>> for form data.
>>>
>>> There wouldn't have to be any backwards incompatible changes, and usage
>>> of `request.DATA` (or whatever better name there might be, perhaps simply
>>> `request.data`) would be entirely optional for using with generic request
>>> parsing, instead of form data only.
>>>
>>>
>>> > Where should request.FILE go in that case
>>>
>>> request.FILES would be populated by form data as normal, and would be
>>> empty on JSON or other submissions.  In order to support multipart parsing
>>> the request parsing API would need to provide for parsers that support file
>>> upload, in a similar way that REST framework currently does.
>>>
>>> > Would request.POST just be a call to request.DATA?
>>>
>>> That's an open question, but I'd probably expect it to only return data
>>> if the request contains multipart or url-encoded form data.  (Ie. the
>>> behaviour wouldn't change.)
>>>
>>> Cheers,
>>>
>>>   Tom
>>>
>>> On Wednesday, 4 September 2013 12:33:00 UTC+1, Stefan Berder wrote:

 Tom,
 I agree that the middleware solution is not the best and in my mind
 creates fragmentation of the same type of request handling.

 A generic content-type framework would make the request parsing more
 flexible, stronger to change in the future and open the door to any type.

 I'm curious about the choice of request.DATA though, when doing a POST
 request, I expect the data to be in the POST dictionary and nowhere else.
 Creating a request.DATA attribute would break compatibility with old code
 and seem to me less intuitive. Where should request.FILE go in that case?
 Would request.POST just be a call to request.DATA?

 Stefan

 On Wednesday, 4 September 2013 18:13:12 UTC+8, Tom Christie wrote:
>
> Hi Stefan,
>
> Sure, I'd be interested in seeing us improve how we deal with JSON
> requests and responses.
>
> My preference would be to introduce a request parsing and response
> rendering API that allows us to support not just JSON, but any media type
> that has a parser installed for it.  (I've commented on some of this
> before, 
> here,
> although I think I'm warming towards the idea that it's probably about 
> time
> we started addressing at least some of this in core.)
>
> Unsurprisingly I'd suggest the same general approach that is used in
> REST framework - A lazy `request.

Re: Support POST of application/json content type

2013-09-04 Thread Jonathan Slenders
Would that mean that the object returned by request.DATA/POST/whatever 
could be a different type, depending on what the user posted?

I don't want to see code like:

if isinstance(request.DATA, YamlObject): ...
elif isinstance(request.DATA, dict): ...

although, I'm not sure how any view could handle any random content-type...



Le mercredi 4 septembre 2013 13:57:29 UTC+2, Marc Tamlyn a écrit :
>
> The thing with request.POST is that it's kinda unintuitive when extended 
> to other HTTP methods (e.g. PUT). This is why the old request.raw_post_data 
> was renamed request.body.
>
> request.POST would behave in the expected traditional web way of picking 
> up form encoded POST data, which would also be available in request.DATA as 
> well, but request.DATA is the "new" way of doing it. Personally, I'd 
> lowercase it though, to remove confusion with the PHP $POST $GET $REQUEST 
> which we mimic on the request object. The generally have different use 
> cases anyway - one for complex web things and the other for standard web 
> browsers.
>
> (the above is what tom said...)
>
> Tom - what else do you have in DRF's Request that you would need?
>
>
> On 4 September 2013 12:56, Tom Christie 
> > wrote:
>
>> > Creating a request.DATA attribute would break compatibility with old 
>> code and seem to me less intuitive.
>>
>> The implementation would ensure `request.POST` would still be populated 
>> for form data.
>>
>> There wouldn't have to be any backwards incompatible changes, and usage 
>> of `request.DATA` (or whatever better name there might be, perhaps simply 
>> `request.data`) would be entirely optional for using with generic request 
>> parsing, instead of form data only.
>>
>>
>> > Where should request.FILE go in that case
>>
>> request.FILES would be populated by form data as normal, and would be 
>> empty on JSON or other submissions.  In order to support multipart parsing 
>> the request parsing API would need to provide for parsers that support file 
>> upload, in a similar way that REST framework currently does.
>>
>> > Would request.POST just be a call to request.DATA?
>>
>> That's an open question, but I'd probably expect it to only return data 
>> if the request contains multipart or url-encoded form data.  (Ie. the 
>> behaviour wouldn't change.)
>>
>> Cheers,
>>
>>   Tom
>>
>> On Wednesday, 4 September 2013 12:33:00 UTC+1, Stefan Berder wrote:
>>>
>>> Tom,
>>> I agree that the middleware solution is not the best and in my mind 
>>> creates fragmentation of the same type of request handling.
>>>
>>> A generic content-type framework would make the request parsing more 
>>> flexible, stronger to change in the future and open the door to any type.
>>>
>>> I'm curious about the choice of request.DATA though, when doing a POST 
>>> request, I expect the data to be in the POST dictionary and nowhere else. 
>>> Creating a request.DATA attribute would break compatibility with old code 
>>> and seem to me less intuitive. Where should request.FILE go in that case? 
>>> Would request.POST just be a call to request.DATA?
>>>
>>> Stefan
>>>
>>> On Wednesday, 4 September 2013 18:13:12 UTC+8, Tom Christie wrote:

 Hi Stefan,

 Sure, I'd be interested in seeing us improve how we deal with JSON 
 requests and responses.

 My preference would be to introduce a request parsing and response 
 rendering API that allows us to support not just JSON, but any media type 
 that has a parser installed for it.  (I've commented on some of this 
 before, 
 here,
  
 although I think I'm warming towards the idea that it's probably about 
 time 
 we started addressing at least some of this in core.)

 Unsurprisingly I'd suggest the same general approach that is used in 
 REST framework - A lazy `request.DATA` attribute (or similar) that when 
 accessed, inspects the media type on the request, and parses the request 
 stream with an appropriate parser if possible.  The installed parsers can 
 be configured globally, or on a per-request basis.  The existing multipart 
 and form-encoded parsing behaviour would no longer be a special case baked 
 directly into the request object, but instead be the default installed 
 parsers.

 Taking this approach makes it trivial to write views that can handle 
 both JSON and form data, and providing a proper parser API makes it easy 
 for developers to package up and share their own parser implementation, 
 such as YAML, XML and MsgPack.  (And, looking forwards, JSON-based media 
 types such as hypermedia types.)

 In REST framework this behaviour is (by necessity) implemented in a 
 Request object that wraps the underlying HttpRequest, but the same basic 
 implementation can be applied to implementing it directly in the Request 
>

Re: Support POST of application/json content type

2013-09-04 Thread Marc Tamlyn
The thing with request.POST is that it's kinda unintuitive when extended to
other HTTP methods (e.g. PUT). This is why the old request.raw_post_data
was renamed request.body.

request.POST would behave in the expected traditional web way of picking up
form encoded POST data, which would also be available in request.DATA as
well, but request.DATA is the "new" way of doing it. Personally, I'd
lowercase it though, to remove confusion with the PHP $POST $GET $REQUEST
which we mimic on the request object. The generally have different use
cases anyway - one for complex web things and the other for standard web
browsers.

(the above is what tom said...)

Tom - what else do you have in DRF's Request that you would need?


On 4 September 2013 12:56, Tom Christie  wrote:

> > Creating a request.DATA attribute would break compatibility with old
> code and seem to me less intuitive.
>
> The implementation would ensure `request.POST` would still be populated
> for form data.
>
> There wouldn't have to be any backwards incompatible changes, and usage of
> `request.DATA` (or whatever better name there might be, perhaps simply
> `request.data`) would be entirely optional for using with generic request
> parsing, instead of form data only.
>
>
> > Where should request.FILE go in that case
>
> request.FILES would be populated by form data as normal, and would be
> empty on JSON or other submissions.  In order to support multipart parsing
> the request parsing API would need to provide for parsers that support file
> upload, in a similar way that REST framework currently does.
>
> > Would request.POST just be a call to request.DATA?
>
> That's an open question, but I'd probably expect it to only return data if
> the request contains multipart or url-encoded form data.  (Ie. the
> behaviour wouldn't change.)
>
> Cheers,
>
>   Tom
>
> On Wednesday, 4 September 2013 12:33:00 UTC+1, Stefan Berder wrote:
>>
>> Tom,
>> I agree that the middleware solution is not the best and in my mind
>> creates fragmentation of the same type of request handling.
>>
>> A generic content-type framework would make the request parsing more
>> flexible, stronger to change in the future and open the door to any type.
>>
>> I'm curious about the choice of request.DATA though, when doing a POST
>> request, I expect the data to be in the POST dictionary and nowhere else.
>> Creating a request.DATA attribute would break compatibility with old code
>> and seem to me less intuitive. Where should request.FILE go in that case?
>> Would request.POST just be a call to request.DATA?
>>
>> Stefan
>>
>> On Wednesday, 4 September 2013 18:13:12 UTC+8, Tom Christie wrote:
>>>
>>> Hi Stefan,
>>>
>>> Sure, I'd be interested in seeing us improve how we deal with JSON
>>> requests and responses.
>>>
>>> My preference would be to introduce a request parsing and response
>>> rendering API that allows us to support not just JSON, but any media type
>>> that has a parser installed for it.  (I've commented on some of this
>>> before, 
>>> here,
>>> although I think I'm warming towards the idea that it's probably about time
>>> we started addressing at least some of this in core.)
>>>
>>> Unsurprisingly I'd suggest the same general approach that is used in
>>> REST framework - A lazy `request.DATA` attribute (or similar) that when
>>> accessed, inspects the media type on the request, and parses the request
>>> stream with an appropriate parser if possible.  The installed parsers can
>>> be configured globally, or on a per-request basis.  The existing multipart
>>> and form-encoded parsing behaviour would no longer be a special case baked
>>> directly into the request object, but instead be the default installed
>>> parsers.
>>>
>>> Taking this approach makes it trivial to write views that can handle
>>> both JSON and form data, and providing a proper parser API makes it easy
>>> for developers to package up and share their own parser implementation,
>>> such as YAML, XML and MsgPack.  (And, looking forwards, JSON-based media
>>> types such as hypermedia types.)
>>>
>>> In REST framework this behaviour is (by necessity) implemented in a
>>> Request object that wraps the underlying HttpRequest, but the same basic
>>> implementation can be applied to implementing it directly in the Request
>>> object, and would be somewhat easier.
>>>
>>> I'm interested to see Marc suggesting middleware specifically for
>>> handling JSON requests.  That'd work, and would be a simple approach.  My
>>> reservations with that would be:
>>>
>>> * We'd not be making it any easier for users to deal with request
>>> parsing generally.
>>> * There's no way to write views that deal with request data in an
>>> agonistic way, and dealing with differing media types would require
>>> switching based on the media type in the view itself.  For example, the
>>> generic views would stil

Re: Support POST of application/json content type

2013-09-04 Thread Tom Christie
> Creating a request.DATA attribute would break compatibility with old code 
and seem to me less intuitive.

The implementation would ensure `request.POST` would still be populated for 
form data.

There wouldn't have to be any backwards incompatible changes, and usage of 
`request.DATA` (or whatever better name there might be, perhaps simply 
`request.data`) would be entirely optional for using with generic request 
parsing, instead of form data only.

> Where should request.FILE go in that case

request.FILES would be populated by form data as normal, and would be empty 
on JSON or other submissions.  In order to support multipart parsing the 
request parsing API would need to provide for parsers that support file 
upload, in a similar way that REST framework currently does.

> Would request.POST just be a call to request.DATA?

That's an open question, but I'd probably expect it to only return data if 
the request contains multipart or url-encoded form data.  (Ie. the 
behaviour wouldn't change.)

Cheers,

  Tom

On Wednesday, 4 September 2013 12:33:00 UTC+1, Stefan Berder wrote:
>
> Tom,
> I agree that the middleware solution is not the best and in my mind 
> creates fragmentation of the same type of request handling.
>
> A generic content-type framework would make the request parsing more 
> flexible, stronger to change in the future and open the door to any type.
>
> I'm curious about the choice of request.DATA though, when doing a POST 
> request, I expect the data to be in the POST dictionary and nowhere else. 
> Creating a request.DATA attribute would break compatibility with old code 
> and seem to me less intuitive. Where should request.FILE go in that case? 
> Would request.POST just be a call to request.DATA?
>
> Stefan
>
> On Wednesday, 4 September 2013 18:13:12 UTC+8, Tom Christie wrote:
>>
>> Hi Stefan,
>>
>> Sure, I'd be interested in seeing us improve how we deal with JSON 
>> requests and responses.
>>
>> My preference would be to introduce a request parsing and response 
>> rendering API that allows us to support not just JSON, but any media type 
>> that has a parser installed for it.  (I've commented on some of this 
>> before, 
>> here,
>>  
>> although I think I'm warming towards the idea that it's probably about time 
>> we started addressing at least some of this in core.)
>>
>> Unsurprisingly I'd suggest the same general approach that is used in REST 
>> framework - A lazy `request.DATA` attribute (or similar) that when 
>> accessed, inspects the media type on the request, and parses the request 
>> stream with an appropriate parser if possible.  The installed parsers can 
>> be configured globally, or on a per-request basis.  The existing multipart 
>> and form-encoded parsing behaviour would no longer be a special case baked 
>> directly into the request object, but instead be the default installed 
>> parsers.
>>
>> Taking this approach makes it trivial to write views that can handle both 
>> JSON and form data, and providing a proper parser API makes it easy for 
>> developers to package up and share their own parser implementation, such as 
>> YAML, XML and MsgPack.  (And, looking forwards, JSON-based media types such 
>> as hypermedia types.)
>>
>> In REST framework this behaviour is (by necessity) implemented in a 
>> Request object that wraps the underlying HttpRequest, but the same basic 
>> implementation can be applied to implementing it directly in the Request 
>> object, and would be somewhat easier.
>>
>> I'm interested to see Marc suggesting middleware specifically for 
>> handling JSON requests.  That'd work, and would be a simple approach.  My 
>> reservations with that would be:
>>
>> * We'd not be making it any easier for users to deal with request parsing 
>> generally.
>> * There's no way to write views that deal with request data in an 
>> agonistic way, and dealing with differing media types would require 
>> switching based on the media type in the view itself.  For example, the 
>> generic views would still only support form data.  As another example, if 
>> you wanted to add, say, MsgPack support to your application, you'd need to 
>> re-write all your views.
>>
>> From my point of view this is already a solved problem, and I'd really 
>> like to see a generic approach to handling request data, and a 
>> corresponding approach to rendering responses into an appropriate media 
>> type.
>>
>>  All the best,
>>
>>   Tom
>>
>> On Tuesday, 3 September 2013 06:30:04 UTC+1, Stefan Berder wrote:
>>>
>>> Hi,
>>> I looked around the list and couldn't find any mention of this subject.
>>>
>>> In `django.http.request.HttpRequest._load_post_and_files()` there is 
>>> explicit mention of two content type ('multipart/form-data' and 
>>> 'application/x-www-form-urlencoded'), any other content type will get empty 
>>> values for self._post.
>>>

Re: [GSoC] Revamping validation framework and merging django-secure once again

2013-09-04 Thread Russell Keith-Magee
Hi Christopher,

On Tue, Sep 3, 2013 at 9:25 PM, Christopher Medrela  wrote:

> 1. Progress: I've made improvements to admin checks. I've also finished
> implementing filtering and silencing checks. I've rebased my branch against
> master again.
>
> Excellent - I'll take look and get you some feedback.


> 2. I'm afraid that there is too little time to merge django-secure.
> September 16 is
> suggested 'pencils down' date, so there are only less than two weeks (12
> days) +
> one buffer week, because firm 'pencils down' date is September 23. Merging
> django-secure in such little time is actually impossible -- we must
> through out
> this task from schedule. I really apologize for that.
>
> This is obviously disappointing, but it's better to deliver something
complete than a half-attempt. If we can get the core framework into a good
state, merging django-secure is a self-contained task that we can address
as a follow-up commit.

Also -- the GSoC will come to an end, but that doesn't mean your
contributions to Django have to… :-)


> My plan is that this week I will work at documentation (at this moment
> there is
> only a draft). I will also try to implement as much "nice to have" things
> as
> possible. These are:
>
>- Writing tests which would be nice to have. I mean three tests:
>   -   [#20974],
>   -   test for raising error when ImageField is in use but Pillow is
>   not installed,
>   -   test for raising error in `BaseCommand.__init__`.
>- Moving out checks performed in `__init__`.
>- Checking clashes between accessors and GenericForeignKeys.
>- Checks for grouped `choices`.
>
> The second week and the backup week is for deep review. Regarding the
> amount
> of comments I got during the first review, I guess I need *at least* one
> week
> for deep review.
>

This sounds like a reasonable plan -- it's a bunch of relatively easy
individual tests, each of which will individually improve the current
situation, but each of which could also be omitted if time becomes a factor.

When you're ready for another deep review, let me know and I'll run over
the code again.

[#20974] https://code.djangoproject.com/ticket/20974
>
> 3. As I said, I've implemented both filtering and silencing system checks.
>
> You can run only a subset of checks like that:
>
> ./manage.py check auth -t tag1 --tag tag2
>
> This command will run only these checks which are labeled with `tag1` or
> `tag2`
> tags and only `auth` app will be validated. If there is no app name, all
> apps
> are checked. If there is no tag name, all checks are performed.
>
> Your check function can be labeled in this way:
>
> from django.core.checks import register, tag
>
> @tag('mytag')
> def my_check_function(apps, **kwargs):
> # apps is a list of apps that should be validated; if None, all
> apps
> # should be checked.
> return []
>
> register(my_check_function)
>
> The `tag` decorator works only for entry-point functions, e.g. these one
> passed
> to `register` function. It doesn't work for checks
> functions/methods/classmethods which are called by entry-point functions
> (directly or indirectly).
>

I've just bounced this off Aymeric and he pointed out something
interesting. We have a precedent for this in another area -- template tags.
You can use a decorator to register a template tag, and that register
decorator can also take arguments to control tag naming, etc.

Once he pointed this out, it seemed obvious that this is what we should be
doing here, too -- after all, the use case is almost identical (registering
a function with a central repository, with some optional arguments
associated with the registration.

So - instead of having a @tag decorator, we should be modifying register to
be a decorator, taking optional arguments that lets you specify tags.
Depending on how easy the internals for this work, we could do either:

@register('mytag')
@register('othertag')
def my_check_function(apps, **kwargs):
…

or

@register('mytag', 'othertag')
def my_check_function(apps, **kwargs):
…

And, of course, if you don't want to use decorator syntax, you can invoke
the decorator directly.

To silence a specific error/warning, you need to append its `id` to
> SILENCED_SYSTEM_CHECKS setting. The `id` could be any string, but we use
> the
> following convension: "E001" for core errors, "W002" for core warnings,
> "applabel.E001" for errors raised by an custom app (including contrib
> apps, i.e.
> "sites.E001"). The error/warning number is unique to an app, e.g.
> "sites.E001",
> "admin.E001" and "E001" are all allowed, but "E001" and "W001" are not OK.
> You
> should use "E001" and "W002". To create an error/warning with given id,
> pass it
> as a keyword argument:
>
> Error('Message', hint=None, obj=invalid_object, id='myapp.E001')
>

Looks good to me.


> 4. More important changes in code:
>
> - Introduced RAW_SETTINGS_MODULE [1]. I use it in compatibility checks to
> te

Re: Support POST of application/json content type

2013-09-04 Thread Stefan Berder
Tom,
I agree that the middleware solution is not the best and in my mind creates 
fragmentation of the same type of request handling.

A generic content-type framework would make the request parsing more 
flexible, stronger to change in the future and open the door to any type.

I'm curious about the choice of request.DATA though, when doing a POST 
request, I expect the data to be in the POST dictionary and nowhere else. 
Creating a request.DATA attribute would break compatibility with old code 
and seem to me less intuitive. Where should request.FILE go in that case? 
Would request.POST just be a call to request.DATA?

Stefan

On Wednesday, 4 September 2013 18:13:12 UTC+8, Tom Christie wrote:
>
> Hi Stefan,
>
> Sure, I'd be interested in seeing us improve how we deal with JSON 
> requests and responses.
>
> My preference would be to introduce a request parsing and response 
> rendering API that allows us to support not just JSON, but any media type 
> that has a parser installed for it.  (I've commented on some of this 
> before, 
> here,
>  
> although I think I'm warming towards the idea that it's probably about time 
> we started addressing at least some of this in core.)
>
> Unsurprisingly I'd suggest the same general approach that is used in REST 
> framework - A lazy `request.DATA` attribute (or similar) that when 
> accessed, inspects the media type on the request, and parses the request 
> stream with an appropriate parser if possible.  The installed parsers can 
> be configured globally, or on a per-request basis.  The existing multipart 
> and form-encoded parsing behaviour would no longer be a special case baked 
> directly into the request object, but instead be the default installed 
> parsers.
>
> Taking this approach makes it trivial to write views that can handle both 
> JSON and form data, and providing a proper parser API makes it easy for 
> developers to package up and share their own parser implementation, such as 
> YAML, XML and MsgPack.  (And, looking forwards, JSON-based media types such 
> as hypermedia types.)
>
> In REST framework this behaviour is (by necessity) implemented in a 
> Request object that wraps the underlying HttpRequest, but the same basic 
> implementation can be applied to implementing it directly in the Request 
> object, and would be somewhat easier.
>
> I'm interested to see Marc suggesting middleware specifically for handling 
> JSON requests.  That'd work, and would be a simple approach.  My 
> reservations with that would be:
>
> * We'd not be making it any easier for users to deal with request parsing 
> generally.
> * There's no way to write views that deal with request data in an 
> agonistic way, and dealing with differing media types would require 
> switching based on the media type in the view itself.  For example, the 
> generic views would still only support form data.  As another example, if 
> you wanted to add, say, MsgPack support to your application, you'd need to 
> re-write all your views.
>
> From my point of view this is already a solved problem, and I'd really 
> like to see a generic approach to handling request data, and a 
> corresponding approach to rendering responses into an appropriate media 
> type.
>
>  All the best,
>
>   Tom
>
> On Tuesday, 3 September 2013 06:30:04 UTC+1, Stefan Berder wrote:
>>
>> Hi,
>> I looked around the list and couldn't find any mention of this subject.
>>
>> In `django.http.request.HttpRequest._load_post_and_files()` there is 
>> explicit mention of two content type ('multipart/form-data' and 
>> 'application/x-www-form-urlencoded'), any other content type will get empty 
>> values for self._post.
>>
>> Given that a lot of user form interaction is now happening through 
>> 'XMLHttpRequest', I think that the 'application/json' content type should 
>> be supported. A lot of javascript libraries will use json as the default 
>> format:
>> * angularjs: http://docs.angularjs.org/api/ng.$http, see "Setting HTTP 
>> Headers"
>> * emberjs: 
>> https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L974
>> * backbone: http://backbonejs.org/#Sync
>> * jquery: http://api.jquery.com/jQuery.ajax/ (the only one using 
>> 'application/x-www-form-urlencoded' by default)
>>
>> I'm trying primarily to create a discussion on the subject and am ready 
>> to provide the code for it as I had to write it. This would help avoid 
>> hacks to handle the request object in my view. 
>>
>> I know there are some apps to handle API construction (django-tastypie, 
>> django-rest, django-piston and certainly others) they use either request 
>> wrappers or request handling in their views.
>>
>> Stefan
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails fr

Re: Support POST of application/json content type

2013-09-04 Thread Tom Christie
Hi Stefan,

Sure, I'd be interested in seeing us improve how we deal with JSON requests 
and responses.

My preference would be to introduce a request parsing and response 
rendering API that allows us to support not just JSON, but any media type 
that has a parser installed for it.  (I've commented on some of this 
before, 
here,
 
although I think I'm warming towards the idea that it's probably about time 
we started addressing at least some of this in core.)

Unsurprisingly I'd suggest the same general approach that is used in REST 
framework - A lazy `request.DATA` attribute (or similar) that when 
accessed, inspects the media type on the request, and parses the request 
stream with an appropriate parser if possible.  The installed parsers can 
be configured globally, or on a per-request basis.  The existing multipart 
and form-encoded parsing behaviour would no longer be a special case baked 
directly into the request object, but instead be the default installed 
parsers.

Taking this approach makes it trivial to write views that can handle both 
JSON and form data, and providing a proper parser API makes it easy for 
developers to package up and share their own parser implementation, such as 
YAML, XML and MsgPack.  (And, looking forwards, JSON-based media types such 
as hypermedia types.)

In REST framework this behaviour is (by necessity) implemented in a Request 
object that wraps the underlying HttpRequest, but the same basic 
implementation can be applied to implementing it directly in the Request 
object, and would be somewhat easier.

I'm interested to see Marc suggesting middleware specifically for handling 
JSON requests.  That'd work, and would be a simple approach.  My 
reservations with that would be:

* We'd not be making it any easier for users to deal with request parsing 
generally.
* There's no way to write views that deal with request data in an agonistic 
way, and dealing with differing media types would require switching based 
on the media type in the view itself.  For example, the generic views would 
still only support form data.  As another example, if you wanted to add, 
say, MsgPack support to your application, you'd need to re-write all your 
views.

>From my point of view this is already a solved problem, and I'd really like 
to see a generic approach to handling request data, and a corresponding 
approach to rendering responses into an appropriate media type.

 All the best,

  Tom

On Tuesday, 3 September 2013 06:30:04 UTC+1, Stefan Berder wrote:
>
> Hi,
> I looked around the list and couldn't find any mention of this subject.
>
> In `django.http.request.HttpRequest._load_post_and_files()` there is 
> explicit mention of two content type ('multipart/form-data' and 
> 'application/x-www-form-urlencoded'), any other content type will get empty 
> values for self._post.
>
> Given that a lot of user form interaction is now happening through 
> 'XMLHttpRequest', I think that the 'application/json' content type should 
> be supported. A lot of javascript libraries will use json as the default 
> format:
> * angularjs: http://docs.angularjs.org/api/ng.$http, see "Setting HTTP 
> Headers"
> * emberjs: 
> https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L974
> * backbone: http://backbonejs.org/#Sync
> * jquery: http://api.jquery.com/jQuery.ajax/ (the only one using 
> 'application/x-www-form-urlencoded' by default)
>
> I'm trying primarily to create a discussion on the subject and am ready to 
> provide the code for it as I had to write it. This would help avoid hacks 
> to handle the request object in my view. 
>
> I know there are some apps to handle API construction (django-tastypie, 
> django-rest, django-piston and certainly others) they use either request 
> wrappers or request handling in their views.
>
> Stefan
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.